python 3's adoption

X

Xah Lee

* Many functions that return lists now returns “Views†or
“Iterators†Instead. A fucking **** all fucked up shit. A extraneous
“oop engineering†complication. (See: Lambda in Python 3000)

See also:

“Iterators: Signs of Weakness in Object-Oriented Languages†(1992) By
Henry G Baker. http://home.pipeline.com/~hbaker1/Iterator.html
* The cmp() function used in sort is basically gone, users are now
supposed to use the “key†parameter instead. This is a flying-face-
**** to computer science. This would be the most serious fuckup in
python 3. (See: Sorting in Python and Perl)
I did too, when I first heard cmp was to be dumped. But I changed my mind
and now agree with the decision to drop cmp. Custom sorts are nearly
always much better written with key rather than cmp: key adds an O(N)
overheard to the sorting, while cmp makes sorting O(N**2). In other
words, key is *much* faster, and generally easier to write as well.

The reason cmp is a order slower is due to Python lang's limitation
and compiler implementation limitation.

• Sorting in Python and Perl
http://xahlee.org/perl-python/sort_list.html

the python lang, by the very nature of being a dynamic lang, makes it
hard for compiler analize and optimize a sort function call with cmp
argument that is equivalent to a key.

So, for practical reasons, i think a “key†parameter is fine. But
chopping off “cmp†is damaging. When your data structure is complex,
its order is not embedded in some “keyâ€. Taking out “cmp†makes it
impossible to sort your data structure.

in the essay, i also gave a few examples of data structures where you
need a general means to specify the ordering function in order to
sort. Without a cmp, you'll need to munge your data by some decorate-
sort-dedecorate technique.

From another perspective, often it is considered a good principle of
design that the lang be a bit flexible to let programers do what they
want, instead of force them into one way. Python, being a loosely
typed lang, with so-called “duck typingâ€, in contrast to Java or OCaml
in different ways, certainly is more on the lose extreme of the lang
spectrum with respect to code construction. So, i don't see how python
3 people made the decision to removed cmp. (am pretty sure, at least
part of the reason, is a ill attitude towards functional programing
and lambda, lead by Guido.)
There may be a handful of rare applications where there is no obvious way
to convert a cmp function to a key, but they are vanishingly rare. I
think, if you search the archives, Paul Rubin may have come up with one
example. There are a number of recipes for easily converting cmp sorts to
key sorts.

You say that it is rare. You are probably right. Though, that may just
be caused by the language itself and consequently the type of people
who uses it. If Python's lambda is not limited, and the python
community doesn't look down on lambda, it is likely cmp will used
more. The more your data structure becomes complex, the more cmp will
be needed.
I think, in my perfect world, list.sort() and sorted() should continue
being key based, while the standard library contained (perhaps in the
functools module?) a sort function that contains all the bells and
whistles. You want cmp, it's there, and you can pay the extra cost if you
need it. You want to sort multiple lists by the contents of one? One
import away. But keep the general sort() function lean and super-fast.

btw, is something like cmp still available in some module for sort?

Xah
∑ http://xahlee.org/

☄
 
A

Alf P. Steinbach

* Daniel Fetchinson:
Actually not, IMHO. All it does is is to provide incompatibility.


What incompatibility are you exactly talking about?

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.hello

Yes, this is with python 2.6.2 which is in the 2.x line of releases. So?

I gather that your example is about code that technically executes fine with
both versions and produces the same result, i.e. that there is a subset with the
same syntax and semantics.

But 'print' calls that technically execute fine with both versions may and will
in general produce different results.

I.e. not just the syntax but also the semantics have changed:

>>> import sys
>>> sys.version '2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)]'
>>>
>>> print( "2+2 =", 2+2 ) ('2+2 =', 4)
>>> _
>>> import sys
>>> sys.version '3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)]'
>>>
>>> print( "2+2 =", 2+2 ) 2+2 = 4
>>> _



Cheers & hth.,

- Alf
 
D

Daniel Fetchinson

* Print is now a function. Great, much improvement.
Actually not, IMHO. All it does is is to provide incompatibility.


What incompatibility are you exactly talking about?

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
print( 'hello' ) hello
print 'hello'
hello

Yes, this is with python 2.6.2 which is in the 2.x line of releases. So?

I gather that your example is about code that technically executes fine with
both versions and produces the same result, i.e. that there is a subset with
the
same syntax and semantics.

But 'print' calls that technically execute fine with both versions may and
will
in general produce different results.

I.e. not just the syntax but also the semantics have changed:

import sys
sys.version '2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)]'

print( "2+2 =", 2+2 ) ('2+2 =', 4)
_
import sys
sys.version '3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)]'

print( "2+2 =", 2+2 ) 2+2 = 4
_

True. However, as someone else pointed out in a neighbouring thread you can do

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
which gives 100% compatibility as far as print is concerned between 2.6 and 3.x.

So again, what sort of an incompatibility are you talking about
concerning 'print' between 2.6 and 3.x?

Cheers,
Daniel
 
A

Alf P. Steinbach

* Daniel Fetchinson:
* Print is now a function. Great, much improvement.
Actually not, IMHO. All it does is is to provide incompatibility.

What incompatibility are you exactly talking about?

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
print( 'hello' )
hello
print 'hello'
hello

Yes, this is with python 2.6.2 which is in the 2.x line of releases. So?
I gather that your example is about code that technically executes fine with
both versions and produces the same result, i.e. that there is a subset with
the
same syntax and semantics.

But 'print' calls that technically execute fine with both versions may and
will
in general produce different results.

I.e. not just the syntax but also the semantics have changed:

import sys
sys.version
'2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)]'
print( "2+2 =", 2+2 ) ('2+2 =', 4)
_

import sys
sys.version
'3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)]'
print( "2+2 =", 2+2 ) 2+2 = 4
_

True. However, as someone else pointed out in a neighbouring thread you can do

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.2+2 = 4

which gives 100% compatibility as far as print is concerned between 2.6 and 3.x.

That makes the code behave with 3.x syntax and semantics regarding print. I.e.
it chooses one language. It doesn't make them compatible: if they were, then you
wouldn't have to choose.

For example, it doesn't fix up 2.x code that prints tuples: incompatible, it
will still execute but no longer do what it was supposed to do.

But lest you focus down on that rare case, consider 2.x code that contains

print "2+2", 2

All such statements need to be fixed up in a 2->3 transition. Adding __future__
just makes the code invalid, it doesn't give you any shred of compatibility for
this. A code rewrite can be partially automated like 2to3 but the
incompatibility needlessly introduces an additional set of things that Can Go
Wrong(TM), and with Murphy present, as He always is, well.

So again, what sort of an incompatibility are you talking about
concerning 'print' between 2.6 and 3.x?

Syntax and semantics. They're different.


Cheers & hth.,

- Alf
 
D

Daniel Fetchinson

* Print is now a function. Great, much improvement.
Actually not, IMHO. All it does is is to provide incompatibility.

What incompatibility are you exactly talking about?

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
print( 'hello' )
hello
print 'hello'
hello

Yes, this is with python 2.6.2 which is in the 2.x line of releases. So?
I gather that your example is about code that technically executes fine
with
both versions and produces the same result, i.e. that there is a subset
with
the
same syntax and semantics.

But 'print' calls that technically execute fine with both versions may
and
will
in general produce different results.

I.e. not just the syntax but also the semantics have changed:


import sys
sys.version
'2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)]'

print( "2+2 =", 2+2 )
('2+2 =', 4)
_


import sys
sys.version
'3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)]'

print( "2+2 =", 2+2 )
2+2 = 4
_

True. However, as someone else pointed out in a neighbouring thread you
can do

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
from __future__ import print_function
print( "2+2 =", 2+2 )
2+2 = 4

which gives 100% compatibility as far as print is concerned between 2.6
and 3.x.

That makes the code behave with 3.x syntax and semantics regarding print.
I.e. it chooses one language.

It doesn't make them compatible:

Of course it makes them compatible. I'm not saying any print-related
code in python 2.6 is valid python 3 code, but that it is *possible*
to write print-related code in python 2.6 that is also valid in python
3.
if they were, then you wouldn't have to choose.

It seems to me you are arguing with the statement "Any print-related
python 2.6 code is valid python 3 code". Nobody is making this
statement. Let me repeat, what you should be arguing with is "It is
possible to write print-related python 2.6 code that is also valid
python 3 code". Perhaps I didn't make myself clear before, but at
least now I hope it's clear what I mean.

Cheers,
Daniel
 
A

Alf P. Steinbach

* Daniel Fetchinson:
* Print is now a function. Great, much improvement.
Actually not, IMHO. All it does is is to provide incompatibility.
What incompatibility are you exactly talking about?

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
print( 'hello' )
hello
print 'hello'
hello

Yes, this is with python 2.6.2 which is in the 2.x line of releases. So?
I gather that your example is about code that technically executes fine
with
both versions and produces the same result, i.e. that there is a subset
with
the
same syntax and semantics.

But 'print' calls that technically execute fine with both versions may
and
will
in general produce different results.

I.e. not just the syntax but also the semantics have changed:


import sys
sys.version
'2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)]'

print( "2+2 =", 2+2 )
('2+2 =', 4)
_


import sys
sys.version
'3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)]'

print( "2+2 =", 2+2 )
2+2 = 4
_
True. However, as someone else pointed out in a neighbouring thread you
can do

Python 2.6.2 (r262:71600, Aug 21 2009, 12:23:57)
[GCC 4.4.1 20090818 (Red Hat 4.4.1-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
from __future__ import print_function
print( "2+2 =", 2+2 )
2+2 = 4

which gives 100% compatibility as far as print is concerned between 2.6
and 3.x.
That makes the code behave with 3.x syntax and semantics regarding print.
I.e. it chooses one language.

It doesn't make them compatible:

Of course it makes them compatible. I'm not saying any print-related
code in python 2.6 is valid python 3 code, but that it is *possible*
to write print-related code in python 2.6 that is also valid in python
3.
if they were, then you wouldn't have to choose.

It seems to me you are arguing with the statement "Any print-related
python 2.6 code is valid python 3 code". Nobody is making this
statement. Let me repeat, what you should be arguing with is "It is
possible to write print-related python 2.6 code that is also valid
python 3 code". Perhaps I didn't make myself clear before, but at
least now I hope it's clear what I mean.

Perhaps we're in violent agreement. :)

However, the root node of this subthread was my statement about the needless
incompatibility introduced by changing print in 3.x, whether that statement was
correct or reasonable / whatever.

The main problem with the incompatibility is for porting code, not for writing
code from scratch. It's also a problem wrt. learning the language. And I see no
good reason for it: print can't really do more, or less, or more conveniently
(rather, one has to write a bit more now for same effect).


Cheers,

- Alf
 
L

Luis M. González

Please don't post more noise and ad hominem attacks to the group, Steve.

"Ad hominem"?
Please, operor non utor lingua non notus per vulgaris populus.
Gratias ago vos...
 
S

Steve Holden

Alf P. Steinbach wrote:
[...]
The main problem with the incompatibility is for porting code, not for
writing code from scratch. It's also a problem wrt. learning the
language. And I see no good reason for it: print can't really do more,
or less, or more conveniently (rather, one has to write a bit more now
for same effect).

Of course it can do more: it allows you to layer your own print
functionality into the system much more easily than you could with the
print statement.

regards
Steve
 
A

Alf P. Steinbach

* Steve Holden:
Alf P. Steinbach wrote:
[...]
The main problem with the incompatibility is for porting code, not for
writing code from scratch. It's also a problem wrt. learning the
language. And I see no good reason for it: print can't really do more,
or less, or more conveniently (rather, one has to write a bit more now
for same effect).

Of course it can do more: it allows you to layer your own print
functionality into the system much more easily than you could with the
print statement.

Yeah, point. Very minor though. :)


Cheers,

- Alf
 
G

Grant Edwards

* Steve Holden:
Alf P. Steinbach wrote:
[...]
The main problem with the incompatibility is for porting code, not for
writing code from scratch. It's also a problem wrt. learning the
language. And I see no good reason for it: print can't really do more,
or less, or more conveniently (rather, one has to write a bit more now
for same effect).

Of course it can do more: it allows you to layer your own print
functionality into the system much more easily than you could with the
print statement.

Yeah, point. Very minor though. :)

I don't think it's minor at all. Being able to globally
redefine the behavior of "print" for all modules is a big win
when you want to import a module that's too chatty about what
it's doing. The "right" way for modules to chatter about
internals is using the logging module, but not everybody
follows that convention.
 
A

Adam Tauno Williams

* Steve Holden:
Alf P. Steinbach wrote:
[...]
The main problem with the incompatibility is for porting code, not for
writing code from scratch. It's also a problem wrt. learning the
language. And I see no good reason for it: print can't really do more,
or less, or more conveniently (rather, one has to write a bit more now
for same effect).
Of course it can do more: it allows you to layer your own print
functionality into the system much more easily than you could with the
print statement.
Yeah, point. Very minor though. :)

So you get to determine that?

I'd call the whole print thing (a) a legitimate change to increase
consistency and (b) a fairly minor porting nuisance since application
code [as in big-chunks-o-code] almost never contains print statements.
I know at least two shops that have scripts they run on all Python code,
prior to it entering production, to ensure there are no print
statements.
 
A

Alf P. Steinbach

* Adam Tauno Williams:
* Steve Holden:
Alf P. Steinbach wrote:
[...]
The main problem with the incompatibility is for porting code, not for
writing code from scratch. It's also a problem wrt. learning the
language. And I see no good reason for it: print can't really do more,
or less, or more conveniently (rather, one has to write a bit more now
for same effect).
Of course it can do more: it allows you to layer your own print
functionality into the system much more easily than you could with the
print statement.
Yeah, point. Very minor though. :)

So you get to determine that?

I'm sorry, I don't find that question meaningful.

I'd call the whole print thing (a) a legitimate change to increase
consistency and (b) a fairly minor porting nuisance since application
code [as in big-chunks-o-code] almost never contains print statements.
I know at least two shops that have scripts they run on all Python code,
prior to it entering production, to ensure there are no print
statements.


Considering that in your opinion "application code [as in big-chunks-o-code]
almost never contains print statements", is the point about being able to
replace print, as you see it, more than a minor point?


Cheers & sorry for not grokking your question,

- Alf
 
J

John Bokma

Xah Lee said:
Someone is badmouthing me, and it has been doing so over the years. I
feel obliged to post a off topic relpy. See:

• DreamHost.com and A Incidence of Harassment
http://xahlee.org/Periodic_dosage_dir/t2/harassment.html

Dreamhost is not the only ISP that has agreed with me in the past
regarding your spamming. And yes, it's spamming if you copy paste an
article from your web site with the link to that site and cross post it
to as many groups as your Usenet provider allows for. Thank goodness
that GG has a limit on how many groups you can spam at a time.

Post to on-topic groups only, really on-topic groups, not as many as you
can select. And participate like you know do, and nobody will complain
about /how/ you post. And if you cross-post /set a follow-up-to/.

That's netiquette.
 
J

Jonathan Gardner

"Ad hominem"?
Please, operor non utor lingua non notus per vulgaris populus.
Gratias ago vos...

My rough, machine-assisted translation:

"Don't try to use language that the people don't know. Thanks."
 
J

Jonathan Gardner

I did too, when I first heard cmp was to be dumped. But I changed my mind
and now agree with the decision to drop cmp. Custom sorts are nearly
always much better written with key rather than cmp: key adds an O(N)
overheard to the sorting, while cmp makes sorting O(N**2). In other
words, key is *much* faster, and generally easier to write as well.

Imagine what sort() could do if all the keys were platform-native
types. In other words, if you could bypass the Python compare because
all the keys were native int, char, char*, or float. You can't do that
with cmp either.
 
P

Paul Rubin

Steven D'Aprano said:
always much better written with key rather than cmp: key adds an O(N)
overheard to the sorting, while cmp makes sorting O(N**2).

Whaaaaaaaaaa ...... ???? No I don't think so.
 
J

Jonathan Gardner

Why not?  GCC lets you use any statement in an expression:

    #include <stdio.h>

    main()
    {
      int i, x, p=0;
      x = ({ for (i=1; i<=10; i++) p += i; p;});
      printf ("x=%d\n", x);
    }

and C is certainly not a purely functional language.


What about assert, import, and pass?

I think you missed the point about what a functional language is and
is not.

Let me see if I can help clear up that confusion a bit.

In a functional language, you don't use statements. For instance, when
you declare a new function, you call the function-declaring-function
with parameters describing the parameters and body of that function.

In such a language, flow control is very, very strange for those not
familiar with it. For instance, how can you call an "if" function that
only evaluates one or the other branches? In such a case, you're not
making a function call, at least not as you know it. What you're doing
is calling a special kind of function that doesn't evaluate its
parameters until later, if at all.

With the above paradigm, you have to start thinking about the
programming task in a completely different light. Rather than
organizing your code into a sequence of evaluated statements, you
organize it into one giant function that will evaluate its parameters
and return some result. This is a difficult paradigm for programmers
to grasp, and is one reason why Lisp and other functional languages
aren't know for being newbie-friendly.

Whether or not a statement can be used as an expression is really
orthogonal to this conversation.

If "yield", "break", and "continue" were functions, then you could
"call" them from within another function and have the call-ee yield,
break, or continue. For instance:

def do_something():
break()

while 1:
do_something()
# The next line is never reached
do_something_else()

This could be useful for some situations, but it is really, really
confusing and so it's not allowed. Such a function would have to rely
on some type of magic so that it is correctly identified as a yield,
break, or continue, and not a typical function call.

"import" is another case. It does something very special. It assigns
to values in the namespace of the code from which it was called. No
function can do that, at least not without some weird magic. It's
better to leave it as a statement and teach new users that it is very,
very special, than to redefine how functions work with the call-ees
namespace, or make it a common task to muck with such things.

If "while", "for", "try", "if", "def", and "class" were functions,
they would have to be written like so:

if(expr, if-true-expr, if-false-expr)

Note, however, that you can't execute if-true of if-false until AFTER
the if() function is called. That means either we re-define what it
means to call a function, or we have some notation that means "Don't
execute this yet". Either way, it's really, really confusing.

Also, note that statements allow you to combine many statements into
one. Python's rule is that you can't pass statements to a function,
only expression, so you'd have to re-define how that works to allow
some function that would combine multiple statements together.

In the end, print is a great candidate for a function, while the
others are most definitely not. Adding any of them as functions would
mean other, fundamental aspects of Python would have to be re-defined
as well.

I hope this clears up Steve's point about functional languages.
 
J

Jonathan Gardner

Whaaaaaaaaaa ...... ????  No I don't think so.

You're referring to the O(N**2) bit, right? I am sure he knew it was O
(N*log(N)), which is still worse than O(N) for key.

If he didn't, well, Python has some fundamental flaws in its basic
sort algorithm.
 
P

Paul Rubin

Jonathan Gardner said:
...
For instance, how can you call an "if" function ...
If "yield", "break", and "continue" were functions, ...
"import" ... does something very special. It assigns
to values in the namespace of the code from which it was called.
In the end, print is a great candidate for a function,

Reasonable point about import. "If", "yield", "break", and "continue"
are irrelevant if one accepts the flow control argument, although there
is already expression syntax for "if" and "yield". What about assert
and pass?
Also, note that statements allow you to combine many statements into
one. Python's rule is that you can't pass statements to a function,

But if we're going around introducing changes that break things, why not
get rid of that silly restriction?

I don't mind that 3.x is breaking stuff for the sake of improving
things. That's the whole idea of 3.x, after all. What bugs me is that
the improvements are mostly quite superficial, and the breakage seems
often gratuitous. I'd rather see much more drastic changes and
correspondingly much larger improvements.

Right now I rent an apartment in a city where real estate values have
dropped a couple percent in the past few years. So in principle, I
could move to a 2% bigger apartment while paying the same rent, or move
to a similarly sized apartment while paying 2% less. Either of those is
objectively an improvement, but am I going to do it? Hell no--moving
even down the same street is way too big a hassle to even consider doing
it for such a tiny gain. But if the "2%" were replaced by 3x or 5x, the
proposition would be a heck of a lot more attractive, even if I had to
move a larger distance. That's sort of the way I feel about switching
from Python 2.x to 3.x.
 

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
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top