mutable default parameter problem [Prothon]

M

Mark Hahn

Dave said:
Ahh...so the method name is just _spelled_ with an exclamation point?

Yes, a Prothon identifier is the same as a Python identifier except that it
can end with an exclamation mark ( ! )or a question mark ( ? ). These marks
can only appear at the end and there can only be one. It is up to the
programmer to make sure he/she uses them properly.

Exclamation marks are to be used in identifiers if and only if it is a
method that modifies the target in-place.

Question marks are to be used on methods if and only if they return True or
False and nothing else.
IOW, the ! is a token you can use at the end of an identifier, but it
is not actually used by the language itself -

No, the marks are significant to the language just as any other part of the
identifier is.
Seems like a waste to reserve a
symbol for something so rarely needed.

I disagree. In-place modification is significant and happens often.
Ignoring this is dangerous.
Clearly, readability is in the eye of the beholder. :)

How can you argue that the exclamation mark indicating in-place-modification
does not make it more readable? Several other languages feel so also. We
didn't just make this up.
 
C

Christopher T King

Dave said:
Seems like a waste to reserve a
symbol for something so rarely needed.

Lisp and Scheme do the same thing:

(set! a 5) <- sets a variable (i.e. changes its value)
(eq? a 6) <- tests equality (returns true or false)

It's defined precisely because it's not needed often (at least in the !
case): the functions that modify their arguments are few and far between,
so it is best to warn the programmer of this behaviour.

Though ? doesn't have such a pressing case as !, it does make code easier
to read (distinguishing functions that do something from those that make
simple queries).
 
D

Dave Brueck

Christopher said:
Lisp and Scheme do the same thing:

(set! a 5) <- sets a variable (i.e. changes its value)
(eq? a 6) <- tests equality (returns true or false)

It's defined precisely because it's not needed often (at least in the !
case): the functions that modify their arguments are few and far between,
so it is best to warn the programmer of this behaviour.

An apples-to-oranges comparison, IMO - it makes sense to delimit a side
effect in a functional language.

-Dave
 
D

Dave Brueck

Mark said:
Yes, a Prothon identifier is the same as a Python identifier except that it
can end with an exclamation mark ( ! )or a question mark ( ? ). These marks
can only appear at the end and there can only be one. It is up to the
programmer to make sure he/she uses them properly.

Exclamation marks are to be used in identifiers if and only if it is a
method that modifies the target in-place.

Question marks are to be used on methods if and only if they return True or
False and nothing else.


No, the marks are significant to the language just as any other part of the
identifier is.

You cut out my example that elaborated on the questions I was asking:

1) It's just part of the name. So from the language's perspective, whether
you call it appendINPLACE or append! makes no difference?

2) (continuing on #1) that being the case, it's really just a naming
convention, correct? (because the language itself doesn't do anything with
that information - additional checking to enforce that convention, different
functionality, etc)
From what I gather that's a "yes" to both questions.

I disagree. In-place modification is significant and happens often.
Ignoring this is dangerous.

Well, now we're down to disagreeing how often it occurs. I just haven't seen
very many cases in practice where (1) I want to both do something to an
object AND have it return itself in a single step and (2) doing so can be
done in a clear way, and (3) I want to do it for a good reason rather than
just wanting to save a line of code. In the few cases I've seen so far, the
rationale has apparently been to make the code shorter, not necessarily
better.
How can you argue that the exclamation mark indicating in-place-modification
does not make it more readable?

(1) Because in practice I haven't seen the need for it much, so in my mind
it wouldn't be used that much (making it less familiar & therefore more work
to understand the code) and/or it encourages cramming more onto a line just
because you can.

The "print list.append!(5)" is a fine example of this IMO - you've combined
two *completely unrelated* operations for no good reason. Yes, it's just an
example, I know, but it's probably an example of how it'll be commonly
(mis)used. For every one "good" use of the ! form you'll probably have a
thousand uses where the only benefit was that it saved a line of code. <0.5
wink>

(2) It's just a naming convention, so you can't rely on it's presence or
absence as being accurate (probably not a big deal in practice, but
still...)

(3) Cases like w = x.y.z!() would confuse me, as would

ref! = obj.method!
....
x = ref!(5, 6, 7) # what the heck, x == obj?!

-Dave
 
?

=?iso-8859-15?Q?Pierre-Fr=E9d=E9ric_Caillaud?=

Even though ? and ! feel awkward, I still think they make it more
readable.
Does the language enforce the bool return type on the ? variant ?
 
M

Mark Hahn

Pierre-Frédéric Caillaud said:
Does the language enforce the bool return type on the ? variant ?

That's a good idea. I'll throw that out for a vote on the Prothon
discussion group.

You should join our mailing list. We need ideas. The traffic is light so
it won't be much of a bother. We only have 25 to 30 messages a day and
there are no pesky users yet :) We have some really bright people
contributing right now and it is getting quite exciting.

We are in the middle of figuring out how to add classes to Prothon (just as
a design-contract kind of thing) and are about to move on to language
features (like coroutines) of the stackless engine we are built on. We have
Mr. Stackless himself (Christian) helping out so it should go well.
 
M

Mark Hahn

Dave said:
You cut out my example that elaborated on the questions I was asking:
Sorry.

1) It's just part of the name. So from the language's perspective,
whether you call it appendINPLACE or append! makes no difference?

It makes no difference to the interpreter, but to the other Prothon
programmers it makes a difference because it's a convention. Also append!()
is a standard library function so you don't get to change it :)
2) (continuing on #1) that being the case, it's really just a naming
convention, correct? (because the language itself doesn't do anything
with that information - additional checking to enforce that
convention, different functionality, etc)

Yes, Yes.
Well, now we're down to disagreeing how often it occurs. I just
haven't seen very many cases in practice where (1) I want to both do
something to an object AND have it return itself in a single step and
(2) doing so can be done in a clear way, and (3) I want to do it for
a good reason rather than just wanting to save a line of code. In the
few cases I've seen so far, the rationale has apparently been to make
the code shorter, not necessarily better.

There are many clean readable programming conventions that rely on return
values. This is certainly an acceptable construct, right?

while len(list.append!(x)) < 10:
blah blah blah

Compare that to the less readable and less maintainable Python version:

list.append(x)
while len(list) < 10:
blah blah
list.append(x) # duplicate code

I can come up with many more. I think when you have been without a language
feature for a while you tend to block it out of your mind.
(1) Because in practice I haven't seen the need for it much,

You don't look for it because in the back of your mind you know you can't
use it.
it encourages
cramming more onto a line just because you can.

You are being pretty negative here. Not everyone is out to cram more into a
line. Give people a little more credit.
The "print list.append!(5)" is a fine example of this IMO - you've
combined two *completely unrelated* operations for no good reason.
Yes, it's just an example, I know, but it's probably an example of
how it'll be commonly (mis)used. For every one "good" use of the !
form you'll probably have a thousand uses where the only benefit was
that it saved a line of code. <0.5 wink>

I don't think I commited any big sin. It seemed plenty readable to me.
Combining operations on one line is done all the time. I suppose you would
code this:

x = a + b
x = x * c
print x

instead of this:

print (a+b) * c
(2) It's just a naming convention, so you can't rely on it's presence
or absence as being accurate (probably not a big deal in practice, but
still...)

All programming involves trust. Any programmer can obfuscate his code a
million ways.
(3) Cases like w = x.y.z!() would confuse me, as would

ref! = obj.method!

You are confused pretty easily. Maybe because you aren't used to them.
They read easily to me.
x = ref!(5, 6, 7) # what the heck, x == obj?!

ref! is invalid by convention and obj?! would throw a syntax exception.
 
C

Christian Tismer

Mark Hahn wrote:

....
2) Evaluate the default expression once at each call time when the default
value is needed. The default expression would be evaluated in the context
of the function definition (like a closure).
Comments? How much Python code would these different proposals break?

I think not so very much.
The default mutable parameters have been abused to keep
class-like state. Default parameters in general have also been
used to speed up object lookup on certain speed contests.

Both usages are obsolete, since the same effect can be
achieved with a local function sitting in a scope,
from where it can use mutables it it needs to.

So I don't see many remaining advantages, and I think it is
a good idea to make the defaults less sticky.

+1 for 2)

ciao - chris

--
Christian Tismer :^) <mailto:[email protected]>
Mission Impossible 5oftware : Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9a : *Starship* http://starship.python.net/
14109 Berlin : PGP key -> http://wwwkeys.pgp.net/
work +49 30 89 09 53 34 home +49 30 802 86 56 mobile +49 173 24 18 776
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
 
M

Mark Hahn

Christian said:
I think not so very much.
The default mutable parameters have been abused to keep
class-like state. Default parameters in general have also been
used to speed up object lookup on certain speed contests.

Both usages are obsolete, since the same effect can be
achieved with a local function sitting in a scope,
from where it can use mutables it it needs to.

So I don't see many remaining advantages, and I think it is
a good idea to make the defaults less sticky.

+1 for 2)

I'm glad you voted that way because I implemented #2 a few days ago :-o

Not that I couldn't change it.
 
?

=?iso-8859-15?Q?Pierre-Fr=E9d=E9ric_Caillaud?=

That's a good idea.

In fact I'm not that sure anymore. I like the fact Python operators like
"or" and "and" return values themselves and not booleans ; that's
extremely useful. Thus imposing boolean return types to these "?" method
might break some usability. Then again, it might also be a good idea, but
it needs somoe thinking !
You should join our mailing list. We need ideas. The traffic is light

Done !
and are about to move on to language
features (like coroutines) of the stackless engine we are built on.

Very good !
 
A

Antoon Pardon

Op 2004-06-25 said:
There are many clean readable programming conventions that rely on return
values. This is certainly an acceptable construct, right?

while len(list.append!(x)) < 10:
blah blah blah

Compare that to the less readable and less maintainable Python version:

list.append(x)
while len(list) < 10:
blah blah
list.append(x) # duplicate code

I can come up with many more. I think when you have been without a language
feature for a while you tend to block it out of your mind.

Well personnally I would solve this with a more general loop construct.

Something like: (Pseudo code)

loop:
list.append(x)
while len(list) < 10:
blah blah.


The more general construct would be something like:

loop:
code
while condition1:
code
else:
exit code if condition1 fails
while condition2:
code
else:
exit code if condion2 fail


Does prothon provide for such a general loop?
 
M

Mark Hahn

Antoon Pardon said:
Well personnally I would solve this with a more general loop construct.

Something like: (Pseudo code)

loop:
list.append(x)
while len(list) < 10:
blah blah.


The more general construct would be something like:

loop:
code
while condition1:
code
else:
exit code if condition1 fails
while condition2:
code
else:
exit code if condion2 fail

This seems non-intuitive to me. Also how would you know the "while" was not
a regular "while"? Even if the parser could figure it out, the reader would
be confused.

BTW: Your code example has the "while" indentation not aligning with
anything above which is illegal indentation.
 
P

Paul Rubin

Mark Hahn said:
Yes, a Prothon identifier is the same as a Python identifier except that it
can end with an exclamation mark ( ! )or a question mark ( ? ). These marks
can only appear at the end and there can only be one. It is up to the
programmer to make sure he/she uses them properly.

How do you parse

a!=b
 
M

Mark Hahn

Paul said:
How do you parse

a!=b

As a! = b. Symbols are extracted by the lexer from left to right. Luckily
accidently typing "a != b" as "a!=b" would cause a parser error since
assignments aren't legal in expressions.

Now that I see this example, maybe it would be a good idea to not allow it
because of it's ambiguity. I'll put that up for a vote on our list.
 
A

Antoon Pardon

Op 2004-06-28 said:
This seems non-intuitive to me. Also how would you know the "while" was not
a regular "while"? Even if the parser could figure it out, the reader would
be confused.

These are details. If you want to do it with an other keyword, that is
fine by me. I'm interrested in the functionality, not in a particular
implementation. One possibility would be to not allow what you call
a regular while, all loop constructs would need to start with a loop
statement.

An other possibility would be the "and while" construction that
was dicussed here. Something like

while condition1:
loopcode
else
exitcode
and while condition2:
loopcode
else
exitcode.
BTW: Your code example has the "while" indentation not aligning with
anything above which is illegal indentation.

I know. This is one reason I hate indentation as grammatical
information. Some possible language constructs don't have a structure
that is easily fitted in such a mold. You then see that such constructs
are disregarded because of layout problems, not on lack of merrit
for such a language construct.

It also makes it sometimes difficult to have your program follow
the logical structure of your program. e.g. if you have code
like this:

loop:
loopcode1
and while condition
loopcode2

You could simulate it like this

while true:
loopcode1
if not condition: break
loopcode2

But in order to reflect the logical structure of above I would prefer
to write the if alliged with the while. But that of course is not
possible.
 
P

Paul Rubin

Christopher T King said:
Lisp and Scheme do the same thing:

(set! a 5) <- sets a variable (i.e. changes its value)
(eq? a 6) <- tests equality (returns true or false)

Actually just Scheme. Traditional Lisp uses (setq a 5) and (eq a 6).
For less frequently used predicates, Lisp sometimes uses the -p convention,
similar to your ? convention.
 
M

Mark Hahn

Antoon said:
These are details. If you want to do it with an other keyword, that is
fine by me. I'm interrested in the functionality, not in a particular
implementation. One possibility would be to not allow what you call
a regular while, all loop constructs would need to start with a loop
statement.

An other possibility would be the "and while" construction that
was dicussed here. Something like

while condition1:
loopcode
else
exitcode
and while condition2:
loopcode
else
exitcode.

You should bring this up on the Prothon mailing list. It would need to be
discussed at length.
 

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,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top