Why we will use obj$func() often

M

Mike C. Fletcher

Paul Prescod wrote:
....
Yes, people are irrational. But if you care about language popularity
you have to take that into account. Else you end up with a language
that never goes mainstream like Lisp.

Oooh, lovely double entendre there... ;)

You get a smiley for that one :) .
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/
 
P

Paul Prescod

Mike said:
Paul Prescod wrote:
...



Oooh, lovely double entendre there... ;)

You get a smiley for that one :) .

I wish I were smart enough to do that purposefully. ;)

Paul Prescod
 
G

Greg Ewing

Mark said:
Yes, many people are afraid to try new things. That is a shame.

It's not a matter of being afraid, it's a matter of having
enough spare time and being interested enough to learn enough
about the new language to try it out. The more different Prothon
is from Python, the greater the barrier will be to Python
people, and the fewer of them there will be that can spare the
time to dabble in it.
 
G

Greg Ewing

Mark said:
Well I have a problem now. I gave people on my mailing list a choice
between $var, `var, ~var, and ^var. The current tally is four votes for
$var and none for any of the others. According to your criteria, $var is
the worst and ~var should be the best. Am I correct?

Not necessarily. It can be very hard to analyse these sorts
of things, since people who have an opinion tend to know what
appeals to them and what doesn't, but not why. The pattern
recognition processess involved seem to happen in a part of
the brain that's not accessible to introspection.

My feeling is that ` and ~ are too inconspicuous, $ is
too conspicuous, and ^ has the wrong sort of connotations
(it looks like it's pointing to something somewhere else,
rather than at "myself").
 
G

Greg Ewing

Mark said:
I just meant that people "pre-judge" Prothon based on it's looks.

That argument might make sense if looks were irrelevant to
the usability of a language, but they're not -- looks have
a lot to do with readability. It's probably fair to say
that readability is *all* about looks.
 
G

Greg Ewing

Donn said:
I remember VMS library functions like RMS$PARSE etc.
This basically goes along with the argument above - it's
a single identifier, $ is not punctuation.

Also traditional Basic with A$, B$, etc. There, too, the
$ is considered part of the name -- A was a different
variable from A$, etc.

It seems to work best when the identifier is all upper
case, though. Putting $ amongst lower-case letters looks
goofier.
 
G

Greg Ewing

Mark said:
The whole point is to make things simpler, more readable, and more
efficient, but when people see the & symbol they somehow automatically think
it's complex.

The feature itself might not be complex, but it's
unfamiliar, since it's not quite like anything in any
other language they're likely to be familiar with.
So it makes learning the language a more complex
exercise, since it's one more new thing to learn.

It's also something that will be quite rarely used,
and is totally non-suggestive of its meaning, so I
expect people will be looking it up in the manual a
lot before it finally gets internalised.

On the other hand, replacing it with a keyword such
as "outer" would make it highly suggestive, to the
point where I'd wager most people wouldn't have to
look it up at all.

This is a big advantage that words have over
punctuation -- you have much more scope for choosing
one that means something to people.
 
G

Greg Ewing

Mark said:
The advantage of prefix symbols that Ruby and Prothon use right now is that
the compiler and the program reader don't have to scan the code at all to
see what scope the var belongs to. When you see the & you know it's in the
surrounding function,

Hang on a minute. Do you literally mean the immediately
surrounding function, and not one further out? In

def f():
def g():
def h():
&x = 42
h()
g()
print x

does the &x in h refer to the x in f? If it does, then I
don't see how you can deduce that in a single pass. If it
doesn't, then how do you refer to the x in f from h?
 
G

Greg Ewing

David said:
Python added "read access" to external variables, so they must have
considered "write access" as well. I don't know the history, but I
would guess the reason they didn't allow this is the same as the
reason they don't allow GOTO. Yes it is powerful, but it might
encourage bad programming.

Actually, it was more that there wasn't any single obvious
way of providing write access that blends in with Python's
"assignment is implicit declaration" flavour. Rather than
pick one at random, it was decided to just provide read
access to begin with and leave anything else to later.
 
M

Mark Hahn

Greg Ewing said:
Hang on a minute. Do you literally mean the immediately
surrounding function, and not one further out? In

def f():
def g():
def h():
&x = 42
h()
g()
print x

does the &x in h refer to the x in f? If it does, then I
don't see how you can deduce that in a single pass. If it
doesn't, then how do you refer to the x in f from h?

You cannot. Yes it literally means the immediately surrounding function.
In your example, I can't think of any scheme we've discussed that accesses x
in function f. Python surely cannot.

I understand this is quite limiting, but it's simple. As always, I'm open to
suggestions...
 
M

Mike C. Fletcher

Mark said:
....

You cannot. Yes it literally means the immediately surrounding function.
In your example, I can't think of any scheme we've discussed that accesses x
in function f. Python surely cannot.
Well, not yet, it was explicitly not implemented until something elegant
came along IIRC.
I understand this is quite limiting, but it's simple. As always, I'm open to
suggestions...
How about:

.this (surrounding scope, often an object)
..this (surrounding scope + 1, such as a module or a nested-class'
parent

Seems elegant in a certain way. The construct is reminiscent of
directory specifiers, and meshes nicely with the attribute access
syntax. Gets a little unwieldy if you're having hugely nested
constructs, but then that's already unwieldy, so more pain too them :) .

Have fun,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/
 
M

Michal Vitecek

Mark said:
I just meant that people "pre-judge" Prothon based on it's looks.

i wouldn't use a language whose "look" i don't like. i prefer my code
to be well readable and maintable even after a longish time. many
symbols ($,&,^, etc.) make it a big minus for me because i tend to
forget their special meaning very soon. and looking up those characters
all the time is no-go for me.

so when i saw something like 'someObject$someMethod()' and plenty of
'.a = .b + 1' it scared me right away - simply just based on the
"look" of the language.
 
M

Michael Geary

Mark said:
You cannot. Yes it literally means the immediately surrounding
function. In your example, I can't think of any scheme we've
discussed that accesses x in function f. Python surely cannot.

I understand this is quite limiting, but it's simple. As always,
I'm open to suggestions...

Ouch. The way I use nested functions in JavaScript, it's essential to be
able to use names from higher in the scope chain without worrying about how
far up the chain they are.

It's not P*thonic, but JavaScript's solution for this keeps looking better
to me. When you want a local name, you create it with 'var'. When you refer
to a name, it always starts in the current scope and works its way up the
chain until it finds the name.

As with many things, there's a cost and a benefit. The cost is that you
always have to 'var' your local variables. The benefit is that nested
functions and closures become very clean and simple.

-Mike
 
D

Donn Cave

"Mike C. Fletcher said:
How about:

.this (surrounding scope, often an object)
..this (surrounding scope + 1, such as a module or a nested-class'
parent

Now this sounds like runtime namespace lookup. Consider
def g():
print .x
def f():
x = 5
g()

That prints 5, right? Not, I suppose, but that's how object
"scope" works. Nested function scope is at least to some extent
inherently lexical, the way we normally expect it to work - you're
referring to outer code blocks, not just any caller's namespace.
Seems elegant in a certain way. The construct is reminiscent of
directory specifiers, and meshes nicely with the attribute access
syntax. Gets a little unwieldy if you're having hugely nested
constructs, but then that's already unwieldy, so more pain too them :) .

I still think elegant is not possible when this lexical notion
of scope is bolted onto a runtime namespace lookup system (dynamic
scope.) (I cringe with fear when I use these terms, but I swear
I did look the Lisp definitions up.)

Consider
def f():
x = 5
def g():
print x
x = 7
return g
t = f()
t()

Does it print 5 or 7? Of course, we know it's going to be 7,
because we understand this system and know how to use it, but
I'm saying this is perverse in terms of what people ought to
need to understand. (I also think it's an unfortunate feature
to have to support, if it means preserving f()'s entire local
scope dictionary for the lifetime of t.)

But I admit my approach might not allow what I imagine people
would expect in places, either. Suppose in the above, f invoked
g instead of returning it. Then (I think) many would want x to
be 7 in g. My `until a better idea comes along' response would
be `too bad, use a function parameter', and I can talk about the
value of this attitude towards programming, but I don't have
enough charisma to make it popular. Similarly, I would certainly
not allow any function to rebind variables in the caller.

Donn Cave, (e-mail address removed)
 
M

Mark Hahn

Michael Geary said:
It's not P*thonic, but JavaScript's solution for this keeps looking better
to me. When you want a local name, you create it with 'var'. When you refer
to a name, it always starts in the current scope and works its way up the
chain until it finds the name.

Maybe there would be some way to make the "var" keyword totally optional.
But then that still destroys the "no need to look around to to read the
code" principle.
 
G

Greg Ewing

Mark said:
You cannot. Yes it literally means the immediately surrounding function.
In your example, I can't think of any scheme we've discussed that accesses x
in function f. Python surely cannot.

Python can't write to it, but at least it can read it.
Prothon apparently can't even read it.
> As always, I'm open to suggestions...

I can't think of any way to fix this that preserves the
single-pass requirement, short of introducing some kind
of declaration in the scope where the variable is defined.
 
B

Bengt Richter

The feature itself might not be complex, but it's
unfamiliar, since it's not quite like anything in any
other language they're likely to be familiar with.
So it makes learning the language a more complex
exercise, since it's one more new thing to learn.

It's also something that will be quite rarely used,
and is totally non-suggestive of its meaning, so I
expect people will be looking it up in the manual a
lot before it finally gets internalised.

On the other hand, replacing it with a keyword such
as "outer" would make it highly suggestive, to the
point where I'd wager most people wouldn't have to
look it up at all.

This is a big advantage that words have over
punctuation -- you have much more scope for choosing
one that means something to people.

The word "locals" already exists. If it returned a namespace
object instead of a dict proxy when given a nesting-level arg, we
could write

def f():
x = 123
locals(0).x = 123 # synonym
print x # 123
def g():
x = 456
print x # 456
print locals(1).x # 123
locals(1).x = 789
locals(2).x = 101112
print x # 123
g() # 456 then 123
print x # 789
g() # 456 then 789

print x # 101112

exec-ing or eval-ing 'locals(n)' could return a proxy object that would work
like the current proxy dict (i.e., a read-only snapshot except if it happened
to access globals()).

I suppose you could do a declarative form by giving global (or extern or outer)
a nesting level too.

Hoever, I think lhs := rhs as a spelling of find-and-rebind-lhs would cover
most use cases. (Requiring existing and lhs to have been defined first by
some lhs = rhs in the current or some lexically enclosing scope).

You couldn't reach locally shadowed outer variables of the same name, as you could
with locals(n).name, but how often do you really want to do that? Of course,
locals(n) and global/extern/outer(n) and := could be all be implemented.

Regards,
Bengt Richter
 
M

Mark Hahn

Greg said:
On the other hand, replacing it with a keyword such
as "outer" would make it highly suggestive, to the
point where I'd wager most people wouldn't have to
look it up at all.

What do you mean by keyword? Which do you mean?

1) outer x # x is declared to come from outer scope

2) outer.x # outer is prefix replacing &

Form 1 is very non-P*thonic. I was happy to get rid of the global keyword
and I'd hate to see this one show up.

Form 2 would cause more confusion than &var because the reader would just
think it was a local variable and not even think to look it up. At least
the &var would signal that something unusual was happening.

Is there a third usage you mean that I'm missing?
 
G

Greg Ewing

Mark said:
What do you mean by keyword? Which do you mean?

1) outer x # x is declared to come from outer scope

2) outer.x # outer is prefix replacing &

Form 1 is very non-P*thonic. I was happy to get rid of the global keyword
and I'd hate to see this one show up.

I was thinking of it as a direct replacement for &,
so that instead of

&x = y + &z

you'd write

outer x = y + outer z

But if you don't like the look of that, there's
nothing more to be said.
 
M

Mark Hahn

Greg said:
outer x = y + outer z

It's not that I don't like the looks, it's just that I've never seen a
keyword used that way before in Python, have you? I think that would be a
big change for such a small usage case.

My symbol usage is a big change also, but consistent across the board. If
we made that change, one could argue we'd need to do the same replacement
for all my symbols. So we'd be looking at things like this?

outer x = y + global Cmp(global MAX_HGT, h) + self x
move(self ofsx, self ofsy)
if global Cmp(a,b) < 0:
self z = global Z_MIN + outer firstZAttr

I think this would make the language very unwieldy. This is kind of like
Cobol,. the opposite of Perl. Don't you agree?

I guess the whole problem is my insistence on simple scope indentification
by looking at the variable. It causes the var to need to be tagged.

I feel strongly that the Python mixture of declaration (global), default
(where assigned) and broken (closures) is broken overall and has to be fixed
in Prothon. I take this as a given. So I see these possible solutions:

1) My Ruby-like symbols, which I think are readable and fast-compilable.

2) Word-like symbols, which are large, less readable (too me) and
cluttering.

3) Declarations, which cause the compiler and user to look around and are
not Pythonic.

Am I missing any other solutions?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,165
Latest member
JavierBrak
Top