Why return None?

P

Peter Hansen

Martin said:
It seems to be a fairly common pattern for an object-modifying method to
return None - however, this is often quite inconvenient. ....
this is actually getting in my way a lot when scripting Blender - for
instance, I can't say move(Vector([a,b,c]).normalize()), I have to do
a = Vector([a,b,c])
a.normalize()
move(a)

By the way, the second version is much more readable than
the first, so perhaps there is a secondary reason for this
"return None" thing in addition to the more important one...

-Peter
 
P

Paul Rubin

Peter Hansen said:
instance, I can't say move(Vector([a,b,c]).normalize()), I have to do
a = Vector([a,b,c])
a.normalize()
move(a)

By the way, the second version is much more readable than the first,

That's a matter of opinion. The lines are shorter but there are three
times as many of them. I think programmers ought to be able to make
their own choices about this. There are a lot of different styles
that are equally legitimate.
 
A

Alex Martelli

Martin DeMello said:
My main point is that returning None is pretty useless - it 'wastes' the
return value, and doesn't allow method chaining. Returning self allows
you to either use or discard the return value depending on whether
you're interested in it, whereas using None doesn't give you any choice.
The Zen of Python, by Tim Peters
[snipped]
There should be one-- and preferably only one --obvious way to do it.


Not leaving stylistic choice (which would lead to more than one obvious
way to do it) is quite consonant with the Zen of Python. Of course one
can't always reach what's preferable, but "your main point" which is
presumably meant as a criticism of this design choice comes across as
praise: the design choice follows the overall design's philosophy.

Guido doesn't like method chaining, so he made a design choice that did
not allow method chaining, and did not give several equally obvious ways
to perform some typical, important tasks. This consistency between
detailed design decisions and overall philosophy is exactly that Quality
Without a Name which makes Python so great.


Alex
 
A

Alex Martelli

Martin DeMello said:
Ayose said:
If you can use python 2.3 or newer, try with [::-1]
def f(m, n):
... print (m + n)[::-1]
...
f([1,2,3], [10,20,30])
[30, 20, 10, 3, 2, 1]

Thanks! Where can I look this up?

There should be recipes for such handy shortcuts in the Python Cookbook
(the current printed edition doesn't have this one as it only covers
Python 1.5.2 to 2.2, but we're preparing a second edition focusing on
Python 2.3 and 2.4).

In Python 2.4, by the way, reversed(x) [[using the new built-in function
'reversed']] is most often preferable to x[::-1]. reversed returns an
iterator, optimized for looping on, but if you need a list, tuple, etc,
you can just call list(reversed(x)) and so on.


Alex
 
A

Alex Martelli

Paul Rubin said:
Peter Hansen said:
instance, I can't say move(Vector([a,b,c]).normalize()), I have to do
a = Vector([a,b,c])
a.normalize()
move(a)

By the way, the second version is much more readable than the first,

That's a matter of opinion. The lines are shorter but there are three
times as many of them. I think programmers ought to be able to make
their own choices about this. There are a lot of different styles
that are equally legitimate.

But they're not equally Pythonic -- Python's philosophy is that there
should be preferably only one obvious way to do it. It's a target, a
goal, not something that can be actually reached in 100% of the cases,
but it's an excellent idea.


Alex
 
P

Paul Rubin

There should be one-- and preferably only one --obvious way to do it.

Not leaving stylistic choice (which would lead to more than one obvious
way to do it) is quite consonant with the Zen of Python.

Well, what you're left with is that doing it the one obvious way
doesn't work, and you have to do it in some contorted way instead.
 
M

Martin DeMello

Peter Hansen said:
Martin said:
It seems to be a fairly common pattern for an object-modifying method to
return None - however, this is often quite inconvenient. ...
this is actually getting in my way a lot when scripting Blender - for
instance, I can't say move(Vector([a,b,c]).normalize()), I have to do
a = Vector([a,b,c])
a.normalize()
move(a)

By the way, the second version is much more readable than
the first, so perhaps there is a secondary reason for this
"return None" thing in addition to the more important one...

It depends on what you're doing - to me, the first is simply "the
normalised vector (a,b,c)", inlined. It's a single concept, much like an
inlined string is - would you want to do the following?
a = "Hello "
a = a + str(name)
print a

martin
 
M

Martin DeMello

Alex Martelli said:
Not leaving stylistic choice (which would lead to more than one obvious
way to do it) is quite consonant with the Zen of Python. Of course one
can't always reach what's preferable, but "your main point" which is
presumably meant as a criticism of this design choice comes across as
praise: the design choice follows the overall design's philosophy.

I still feel the the One Obvious Way should have been to return self...
Guido doesn't like method chaining, so he made a design choice that did
not allow method chaining, and did not give several equally obvious ways

But that's pretty hard to argue with :)

martin
 
P

Peter Hansen

Martin said:
It depends on what you're doing - to me, the first is simply "the
normalised vector (a,b,c)", inlined. It's a single concept, much like an
inlined string is - would you want to do the following?
a = "Hello "
a = a + str(name)
print a

I'd want to do neither, often. If I had to do either, often,
I would write a function which did the required operations
and I'd call that instead. Then both it and the calling
code are readable. But I suppose that's just me... maybe
others would prefer to repeat things more.

-Peter
 
A

Alex Martelli

Martin DeMello said:
I still feel the the One Obvious Way should have been to return self...

When you design your own language, you get to impose in it what's
obvious to _you_ -- or go the Perl way and try to squeeze in as many
different ways to do every single task as possible so everybody's happy
except those who can't stand bloated languages (who'll stick with
Python;-).

But that's pretty hard to argue with :)

Indeed, it's not meant to be arguable-with;-). Personally I like method
chaining, but it's clearly not the Python way, and I appreciate
consistency and simplicity more than I appreciate picking and choosing
details of my preferred style.


Alex
 
A

Alex Martelli

Paul Rubin said:
Well, what you're left with is that doing it the one obvious way
doesn't work, and you have to do it in some contorted way instead.

If somelist.sort() returned the list there could not possibly be one
obvious way to do it, since both

print somelist.sort()

and

somelist.sort()
print somelist

would be ways to do it, both pretty obvious to different people. [[The
introduction of 'sorted' will muddy 'obviousness' for some, but IMHO it
just changes what the one obvious way is: if you do want an inplace
sort, then somelist.sort(), otherwise then sorted(somelist) when you do
not want to alter somelist in place.]]


Alex
 
A

Antoon Pardon

Op 2004-08-26 said:
If somelist.sort() returned the list there could not possibly be one
obvious way to do it, since both

print somelist.sort()

and

somelist.sort()
print somelist

Then python has already deviated from the one obvious way to do it.
I can do:

a = a + b vs a += b.

or

a = b + c vs a = ''.join(b,c)


The difference between

print somelist.sort()

and

somelist.sort()
print somelist


is IMO of the same order as the difference between


print a + b

and

r = a + b
print r
 
R

Roel Schroeven

Antoon said:
Then python has already deviated from the one obvious way to do it.
I can do:

a = a + b vs a += b.

or

a = b + c vs a = ''.join(b,c)

a = ''.join((b,c))

join doesn't join all it's arguments; it joins all elements from it's
one argument, which should be a sequence. That's a detail though.
The difference between

print somelist.sort()

and

somelist.sort()
print somelist


is IMO of the same order as the difference between


print a + b

and

r = a + b
print r

Not IMO.

print somelist.sort()

has a side-effect (somelist is sorted), which is not clearly visible if
used that way.

a + b doesn't have any side-effects.
IMO, 'print somelist.sort()' is more equivalent to 'print a += b', which
also doesn't work (fortunately).
 
M

Mel Wilson

In Python 2.4, by the way, reversed(x) [[using the new built-in function
'reversed']] is most often preferable to x[::-1]. reversed returns an
iterator, optimized for looping on, but if you need a list, tuple, etc,
you can just call list(reversed(x)) and so on.

Now that it's too late, I wish it were called
'reversing', after reading the story of somebody who got an
iterator, thinking it was a thing. Then made a dictionary
out of it twice, and got one good dict and one empty dict.

'reverse' and 'reversed' remind me of Extended Memory and
Expanded Memory. One was one, and one the other, but which
was which?

Regards. Mel.
 
A

Alex Martelli

Antoon Pardon said:
Then python has already deviated from the one obvious way to do it.

Yep, ever since it let you code 2+3 and 3+2 with just the same effect --
which was from day one, and couldn't have been otherwise. _Preferably_
only one way, but as I said what's preferable can't always be achieved.

Nevertheless, when for some task there _is_ one obvious way to do it,
adding a feature whose main effect would be giving two alternative
obvious ways to do it would be unPythonic.
I can do:

a = a + b vs a += b.

Yes you can, and in the general case get very different effects, e.g.:
[0, 1, 2, 0, 1]

versus:
[0, 1, 2]

So, which one is the obvious way to do it depends on what 'it' is. In
some cases it doesn't matter, just like b+a and a+b are going to have
the same effect when a and b are numbers rather than sequences, and
there's nothing Python can do to fight this -- practicality beats
purity. If you're (when feasible) altering the object to which name 'a'
is bound, a+=b is the obvious way to do it; if you're in any case
rebinding name 'a' and letting the original object stand undisturbed,
'a=a+b' is the one obvious way to do THAT. Not all objects can be
altered, so the first ones of these tasks isn't always going to be
feasible, of course.
or

a = b + c vs a = ''.join(b,c)

You should try out the code you post, otherwise you risk ending up with
code in your face -- ''.join(b, c) will just raise an exception, which
is a VERY different effect from what b + c will give in most cases.
I'll be charitable and assume you meant ''.join((a, b)) or something
like that.

Again, it's only in one very special case that these two very different
'ways to do it' produce the same effect, just like in other different
special cases 'a = b + c' and 'a = c + b' produce the same effect and
there's nothing Python can do about it.

But let's be sensible: if 'it' is joining two strings which are bound to
names b and c, b+c is the only OBVIOUS way to do it. Building a
sequence whose items are b and c and calling ''.join on it is clearly an
indirect and roundabout -- therefore NOT "the one obvious way"! -- to
achieve a result. Proof: it's so unobvious, unusual, rarely used if
ever, that you typed entirely wrong code for the purpose...

Nobody ever even wished for there to never be two sequences of code with
the same end-result. The idea (a target to strive for) is that out of
all the (probably countable) sequences with that property, ONE stands
out as so much simpler, clearer, more direct, more obvious, to make that
sequence the ONE OBVIOUS way. We can't always get even that, as a+b vs
b+a show when a and b are bound to numbers, but we can sure get closer
to it by respecting most of GvR's design decisions than by offering
unfounded, hasty and badly reasoning critiques of them.


The difference between

print somelist.sort()

and

somelist.sort()
print somelist


is IMO of the same order as the difference between


print a + b

and

r = a + b
print r

For a sufficiently gross-grained comparison, sure. And so? In the
second case, if you're not interested in having the value of a+b kept
around for any subsequent use, then the first approach is the one
obvious way; if you ARE, the second, because you've bound a name to it
(which you might have avoided) so you can reuse it (if you have no
interest in such reuse, it's not obvious why you've bound any name...).

In the first case, fortunately the first approach is illegal, the second
one is just fine. Were they exactly equivalent in effect neither would
be the one obvious way for all reasonable observer -- some would hate
the side effect in the first case, some would hate the idea of having
two statements where one might suffice in the second case.

Fortunately the first approach does NOT do the same thing as the second
(it prints out None:) so Python sticks to its design principles. Let
me offer a private libation to whatever deities protect programmers,
that Python was designed by GvR rather than by people able to propose
analogies such as this last one without following through on all of
their implications and seeing why this SHOWS Python is consistent in
applying its own design principles!


Alex
 
A

Antoon Pardon

Op 2004-08-26 said:
Yep, ever since it let you code 2+3 and 3+2 with just the same effect --
which was from day one, and couldn't have been otherwise. _Preferably_
only one way, but as I said what's preferable can't always be achieved.

Nevertheless, when for some task there _is_ one obvious way to do it,
adding a feature whose main effect would be giving two alternative
obvious ways to do it would be unPythonic.


Yes you can, and in the general case get very different effects, e.g.:

And what about

a += b vs a.extend(b)
[0, 1, 2, 0, 1]

versus:
[0, 1, 2]

I wouldn't say you get different effects in *general*. You get the
same effect if you use numbers or tuples or any other immutable
object.
So, which one is the obvious way to do it depends on what 'it' is. In
some cases it doesn't matter, just like b+a and a+b are going to have
the same effect when a and b are numbers rather than sequences, and
there's nothing Python can do to fight this -- practicality beats
purity. If you're (when feasible) altering the object to which name 'a'
is bound, a+=b is the obvious way to do it; if you're in any case
rebinding name 'a' and letting the original object stand undisturbed,
'a=a+b' is the one obvious way to do THAT. Not all objects can be
altered, so the first ones of these tasks isn't always going to be
feasible, of course.


You should try out the code you post, otherwise you risk ending up with
code in your face -- ''.join(b, c) will just raise an exception, which
is a VERY different effect from what b + c will give in most cases.
I'll be charitable and assume you meant ''.join((a, b)) or something
like that.

Again, it's only in one very special case that these two very different
'ways to do it' produce the same effect, just like in other different
special cases 'a = b + c' and 'a = c + b' produce the same effect and
there's nothing Python can do about it.

But let's be sensible: if 'it' is joining two strings which are bound to
names b and c, b+c is the only OBVIOUS way to do it. Building a
sequence whose items are b and c and calling ''.join on it is clearly an
indirect and roundabout -- therefore NOT "the one obvious way"! -- to
achieve a result. Proof: it's so unobvious, unusual, rarely used if
ever, that you typed entirely wrong code for the purpose...

That is just tradition. Suppose the "+" operator wouldn't have worked
on strings an concatenating would from the start been done by joining,
then that would have been the one obvious way to do it.

Nobody ever even wished for there to never be two sequences of code with
the same end-result. The idea (a target to strive for) is that out of
all the (probably countable) sequences with that property, ONE stands
out as so much simpler, clearer, more direct, more obvious, to make that
sequence the ONE OBVIOUS way.

And what if it are three sequences of code with the same end-result,
or four. From what number isn't it a problem any more if two sequences
of that length or more produce the same result.
We can't always get even that, as a+b vs
b+a show when a and b are bound to numbers, but we can sure get closer
to it by respecting most of GvR's design decisions than by offering
unfounded, hasty and badly reasoning critiques of them.

I think that this goal of GvR is a bad one. If someway of doing it
is usefull then I think it should be included and the fact that
it introduces more than one obvious way to do some things shouldn't
count for much.

Sure you shouldn't go the perl-way where things seemed to have
been introduced just for the sake of having more than obvious way
to do things. But eliminating possibilities (method chaining)
just because you don't like them and because they would create
more than one obvious way to do things, seems just as bad to
me.


What I have herad about the decorators is that one of the
arguments in favor of decorators is, that you have to
give the name of the function only once, where tradionally
you have to repeat the function name and this can introduce
errors.

But the same argument goes for allowing method chaining.
Without method chaining you have to repeat the name of
the object which can introduce errors.
For a sufficiently gross-grained comparison, sure. And so? In the
second case, if you're not interested in having the value of a+b kept
around for any subsequent use, then the first approach is the one
obvious way;

No it isn't because programs evolve. So you may think you don't
need the result later on, but that may change, so writing it
the second way, will making changes easier later on.
if you ARE, the second, because you've bound a name to it
(which you might have avoided) so you can reuse it (if you have no
interest in such reuse, it's not obvious why you've bound any name...).

In the first case, fortunately the first approach is illegal, the second
one is just fine. Were they exactly equivalent in effect neither would
be the one obvious way for all reasonable observer -- some would hate
the side effect in the first case, some would hate the idea of having
two statements where one might suffice in the second case.

So? I sometimes get the idea that people here can't cope with
differences in how people code. So any effort must be made
to force people to code in one specific way.
Fortunately the first approach does NOT do the same thing as the second
(it prints out None:) so Python sticks to its design principles. Let
me offer a private libation to whatever deities protect programmers,
that Python was designed by GvR rather than by people able to propose
analogies such as this last one without following through on all of
their implications and seeing why this SHOWS Python is consistent in
applying its own design principles!

That these implications are important is just an implication on the
design principles. If someone doesn't think particular design principles
are that important, he doesn't care that if somethings is changed that
particulat design principle will be violated. Personnaly I'm not
that impressed with the design of python, it is a very usefull language
but having operators like '+=' which have a different kind of result
depending on whether you have a mutable or immutable object is IMO
not such a good design and I wonder what design principle inspired
them.
 
P

Paul Rubin

Antoon Pardon said:
but having operators like '+=' which have a different kind of result
depending on whether you have a mutable or immutable object is IMO
not such a good design and I wonder what design principle inspired them.

+= was added to Python fairly recently (in 2.0, I think) and there was
a lot of agonizing about whether to add it. It was one of those
things like the ?: construction. On the one hand there was the
abstract objection you raise. On the other hand there were lots of
users frustrated at being unable to say v[f(x)] += 1 instead of having
to call f twice or introduce a temp variable or something.
Eventually, practicality beat purity.
 
A

Antoon Pardon

Op 2004-08-27 said:
Antoon Pardon said:
but having operators like '+=' which have a different kind of result
depending on whether you have a mutable or immutable object is IMO
not such a good design and I wonder what design principle inspired them.

+= was added to Python fairly recently (in 2.0, I think) and there was
a lot of agonizing about whether to add it. It was one of those
things like the ?: construction. On the one hand there was the
abstract objection you raise. On the other hand there were lots of
users frustrated at being unable to say v[f(x)] += 1 instead of having
to call f twice or introduce a temp variable or something.
Eventually, practicality beat purity.

Fine practicality beats purity, but then the proponents shouldn't
put that much weight on consistency, because practicality breaks
consistency.

In this case I think the practicality of method chaining beats
the purity of not allowing side-effects in print statements and
of having only one obvious way to do things.

I don't see that much difference in the frustration of having
to write:

t = f(x)
v[t] = v[t] + 1

and the frustration of having to write

lst = f(x)
lst.sort()
lst.reverse()
 
A

Alex Martelli

Antoon Pardon said:
And what about

a += b vs a.extend(b)

I can go on repeating "in the general case [these constructs] get very
different effects" just as long as you can keep proposing, as if they
might be equivalent, constructs that just aren't so in the general case.

Do I really need to point out that a.extend(b) doesn't work for tuples
and strings, while a+=b works as polymorphically as feasible on all
these types? It should be pretty obvious, I think. So, if you want to
get an AttributeError exception when 'a' is a tuple or str, a.extend(b)
is clearly the way to go -- if you want para-polymorphic behavior in
those cases, a+=b. Isn't it obvious, too?
c=a=range(3)
b=range(2)
a+=b
c
[0, 1, 2, 0, 1]

versus:
c=a=range(3)
b=range(2)
a=a+b
c
[0, 1, 2]

I wouldn't say you get different effects in *general*. You get the
same effect if you use numbers or tuples or any other immutable
object.

a+=b is defined to be: identical to a=a+b for immutable objects being
bound to name 'a'; but not necessarily so for mutable objects -- mutable
types get a chance to define __iadd__ and gain efficiency through
in-place mutation for a+=b, while the semantics of a=a+b strictly forbid
in-place mutation. *IN GENERAL*, the effects of a+=b and a=a+b may
differ, though in specific cases ('a' being immutable, or of a mutable
type which strangely chooses to define __add__ but not __iadd__) they
may be identical. Like for a+b vs b+a: in general they may differ, but
they won't differ if the types involved just happen to have commutative
addition, of if a and b are equal or identical objects, i.e., in various
special cases.

"You get different effects *in general*" does not rule out that there
may be special cases (immutable types for one issue,
commutative-addition types for another, etc, etc) in which the effects
do not differ. Indeed, if it was "always" true that you got different
effects, it would be superfluous to add that "in general" qualifier.
Therefore, I find your assertion that you "wouldn't say you get
different effects in *general*" based on finding special cases in which
the effects do not differ to be absurd and unsupportable.

That is just tradition. Suppose the "+" operator wouldn't have worked
on strings an concatenating would from the start been done by joining,
then that would have been the one obvious way to do it.

In a hypothetical language without any + operator, but with both unary
and binary - operators, the one "obvious" way to add two numbers a and b
might indeed be to code: a - (-b). So what? In a language WITH a
normal binary + operator, 'a - (-b)' is nothing like 'an obvious way'.

And what if it are three sequences of code with the same end-result,
or four. From what number isn't it a problem any more if two sequences
of that length or more produce the same result.

To add N integers that are bound to N separate identifiers, there are
(quite obviously) N factorial "sequences of [the same] length" producing
the same result. Is it "a problem"? I guess it may be considered a
minor annoyance, but it would be absurd to try and do something against
it, e.g. by arbitrary rules forbidding addition between variables except
in alphabetical order. Practicality beats purity.
I think that this goal of GvR is a bad one.

I'm sure you're a better language designer than GvR, since you're
qualified to critique, not just a specific design decision, but one of
the pillars on which he based many of the design decisions that together
made Python.
Therefore, I earnestly urge you to stop wasting your time critiquing an
inferiorly-designed language and go off and design your own, which will
no doubt be immensely superior. Good bye; don't slam the door on the
way out, please.
If someway of doing it
is usefull then I think it should be included and the fact that
it introduces more than one obvious way to do some things shouldn't
count for much.

This is exactly Perl's philosophy, of course.
Sure you shouldn't go the perl-way where things seemed to have
been introduced just for the sake of having more than obvious way
to do things. But eliminating possibilities (method chaining)
just because you don't like them and because they would create
more than one obvious way to do things, seems just as bad to
me.

If a language should not eliminate possibilities because its designer
does not like those possibilities, indeed if it's BAD for a language
designer to omit from his language the possibilities he dislikes, what
else should a language designer do then, except include every
possibility that somebody somewhere MIGHT like? And that IS a far
better description of Perl's philosophy than "just for the sake" quips
(which are essentially that -- quips).
What I have herad about the decorators is that one of the
arguments in favor of decorators is, that you have to
give the name of the function only once, where tradionally
you have to repeat the function name and this can introduce
errors.

But the same argument goes for allowing method chaining.
Without method chaining you have to repeat the name of
the object which can introduce errors.

I've heard that argument in favour of augmented assignment operators
such as += -- and there it makes sense, since the item you're operating
on has unbounded complexity... mydict[foo].bar[23].zepp += 1 may indeed
be better than repeating that horrid LHS (although "Demeter's Law"
suggests that such multi-dotted usage is a bad idea in itself, one
doesn't always structure code with proper assignment of responsibilities
to objects and so forth...).

For a plain name, particularly one which is just a local variable and
therefore you can choose to be as simple as you wish, the argument makes
no sense to me. If I need to call several operations on an object I'm
quite likely to give that object a 'temporary alias' in a local name
anyway, of course:
target = mydict[foo].bar[23].zepp
target.pop(xu1)
target.sort()
target.pop(xu3)
target.reverse()
target.pop(xu7)

Doing just the same thing when I don't need intermediate access to the
object between calls that mutate the object and currently return None is
no hardship, just as it isn't when such access IS needed. Note that you
couldn't do chaining here anyway, since pop mutates the object but also
returns a significant value...

No it isn't because programs evolve. So you may think you don't
need the result later on, but that may change, so writing it
the second way, will making changes easier later on.

Ridiculous. Keep around a+b, which for all we know here might be a
million-items list!, by having a name bound to it, without ANY current
need for that object, because some FUTURE version of your program may
have different specs?!
If specs change, refactoring the program written in the sensible way,
the way that doesn't keep memory occupied to no good purpose, won't be
any harder than refactoring the program that wastes megabytes by always
keeping all intermediate results around "just in case".

So? I sometimes get the idea that people here can't cope with
differences in how people code. So any effort must be made
to force people to code in one specific way.

When more than one person cooperates in writing a program, the group
will work much better if there is no "code ownership" -- the lack of
individualized, quirky style variations helps a lot. It's not imposible
to 'cope with differences' in coding style within a team, but it's just
one more roadblock erected to no good purpose. A language can help the
team reach reasonably uniform coding style (by trying to avoid offering
gratuitous variation which serves no real purpose), or it can hinder the
team in that same goal (by showering gratuitous variation on them).

That these implications are important is just an implication on the
design principles. If someone doesn't think particular design principles
are that important, he doesn't care that if somethings is changed that
particulat design principle will be violated. Personnaly I'm not
that impressed with the design of python, it is a very usefull language

Great, so, I repeat: go away and design your language, one that WILL
impress you with its design. Here, you're just waiting your precious
time and energy, as well of course as ours.
but having operators like '+=' which have a different kind of result
depending on whether you have a mutable or immutable object is IMO
not such a good design and I wonder what design principle inspired
them.

Practicality beats purity: needing to polymorphically concatenate two
sequences of any kind, without caring if one gets modified or not, is a
reasonably frequent need and is quite well satisfied by += for example.


Alex
 
A

Alex Martelli

Antoon Pardon said:
Fine practicality beats purity, but then the proponents shouldn't
put that much weight on consistency, because practicality breaks
consistency.

No: "but special cases aren't special enough to break the rules". No
rule was broken by introducing += and friends.

In this case I think the practicality of method chaining beats
the purity of not allowing side-effects in print statements and
of having only one obvious way to do things.

You think one way, GvR thinks another, and in Python GvR wins. Go
design your own language where what you think matters.

I don't see that much difference in the frustration of having
to write:

t = f(x)
v[t] = v[t] + 1

You're repeating (necessarily) the indexing operation, which may be
unboundedly costly for a user-coded type.

and the frustration of having to write

lst = f(x)
lst.sort()
lst.reverse()

Here, no operation is needlessly getting repeated.

If you don't see much difference between forcing people to code in a way
that repeats potentially-costly operations, and forcing a style that
doesn't imply such repetitions, I wonder how your language will look.
Still, I'm much happier thinking of you busy designing your own
wonderful language, than wasting your time and yours here, busy
criticizing what you cannot change.


Alex
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top