By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,098 Members | 1,950 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,098 IT Pros & Developers. It's quick & easy.

UserLinux chooses Python as "interpretive language" of choice

P: n/a
I don't know if you have seen this before, but here goes:

http://text.userlinux.com/white_paper.html

There is a jab at Python, though, mentioning that Ruby is more
"refined".

--
Ville Vainio http://www.students.tut.fi/~vainio24
Jul 18 '05 #1
Share this Question
Share on Google+
49 Replies


P: n/a

"Ville Vainio" <vi********************@spamtut.fi> wrote in message
news:du*************@amadeus.cc.tut.fi...
I don't know if you have seen this before, but here goes:

http://text.userlinux.com/white_paper.html

There is a jab at Python, though, mentioning that Ruby is more
"refined".
I'm not sure about refined, but it does seem to have several
things that I think I'd like. One is a much
better way of handling anonymous functions, aka "blocks."
Another is the pervasive use of the visitor pattern, and
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.

On the other hand, I'm mildly agnostic over the builtin
function versus method issue.

The biggest problem is that I think Python is beginning
to sucumb to the "we're better so we don't have to try
harder" syndrome. One of these days, someone is going
to start chewing up the user base, and for a while it looked
like Ruby might have been it.

John Roth
--
Ville Vainio http://www.students.tut.fi/~vainio24

Jul 18 '05 #2

P: n/a
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.


class ThisIs:
avariable = 'a'
def amethod(self):
return 'b'

thisis = ThisIs()
print thisis.avariable
print thisis.amethod()
import this
print "Read line 2."

--
Steve C. Lamb | I'm your priest, I'm your shrink, I'm your
PGP Key: 8B6E99C5 | main connection to the switchboard of souls.
-------------------------------+---------------------------------------------
Jul 18 '05 #3

P: n/a

"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
news:sl*****************@dmiyu.org...
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.


class ThisIs:
avariable = 'a'
def amethod(self):
return 'b'

thisis = ThisIs()
print thisis.avariable
print thisis.amethod()
import this
print "Read line 2."


I'm not sure what your point is. Your example isn't going
to produce the expected result if you say:

print thisis.amethod

instead of

print thisis.amethod()

That is the place where I find Ruby syntax to be
helpful: the amount of time where I want the method /
function object is *far* lower than the amount of
time I want to call it. It's one of those conundrums
that doesn't seem to have a clean answer, though.

John Roth
Jul 18 '05 #4

P: n/a
"John Roth" <ne********@jhrothjr.com> writes:
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.
Doesn't this suck big time? How can the interpreter tell whether you
are trying to call a function or just want a reference to a callable
object?
harder" syndrome. One of these days, someone is going
to start chewing up the user base, and for a while it looked
like Ruby might have been it.


I dunno. It just doesn't seem likely that people who have "got" Python
would switch to ruby. If the extra features of ruby were really
worthwhile, they would be added to Python (which has happened
before). I trust the Py development team to do the right decision at
all times (apart from ternary operator, obviously ;-).

--
Ville Vainio http://www.students.tut.fi/~vainio24
Jul 18 '05 #5

P: n/a
On Fri, 19 Dec 2003 20:22:38 -0500, "John Roth" <ne********@jhrothjr.com> wrote:

"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
news:sl*****************@dmiyu.org...
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
> a third is the ability to forget the empty parenthesis after
> a function/method call that doesn't require parameters.


class ThisIs:
avariable = 'a'
def amethod(self):
return 'b'

thisis = ThisIs()
print thisis.avariable
print thisis.amethod()
import this
print "Read line 2."


I'm not sure what your point is. Your example isn't going
to produce the expected result if you say:

print thisis.amethod

instead of

print thisis.amethod()

That is the place where I find Ruby syntax to be
helpful: the amount of time where I want the method /
function object is *far* lower than the amount of
time I want to call it. It's one of those conundrums
that doesn't seem to have a clean answer, though.

Ok, for line 2, run this ;-)

class ThisIs:
avariable = 'a'
def amethod(self):
return 'b'
def silly(self):
return 'heh'
silly = property(silly)

thisis = ThisIs()
print thisis.avariable
print thisis.amethod()
print thisis.silly
import sys
class L2(list):
def write(self, s): self.append(s)
sys.stdout = L2()
import this
L2 = ''.join(sys.stdout).splitlines()[2]
sys.stdout = sys.__stdout__
print "Read line 2."
print '... which is:', L2

Regards,
Bengt Richter
Jul 18 '05 #6

P: n/a
Ville Vainio <vi********************@spamtut.fi> wrote:
If the extra features [...] were really
worthwhile, they would be added to Python


Down that path lies madness (i.e. Perl).
Jul 18 '05 #7

P: n/a

John> The biggest problem is that I think Python is beginning to sucumb
John> to the "we're better so we don't have to try harder" syndrome. One
John> of these days, someone is going to start chewing up the user base,
John> and for a while it looked like Ruby might have been it.

Can you give some concrete examples which support your contention?

Skip

Jul 18 '05 #8

P: n/a
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
I'm not sure what your point is.
If you had run it you would have understood it. You didn't run it, did
you?
Your example isn't going to produce the expected result if you say: print thisis.amethod instead of print thisis.amethod()


Well, you kind of got it. Here's the run:

Python 2.3+ (#2, Aug 10 2003, 11:33:47)
[GCC 3.3.1 (Debian)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
class ThisIs: .... avariable = 'a'
.... def amethod(self):
.... return 'b'
.... thisis = ThisIs()
print thisis.avariable a print thisis.amethod() b import this The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those! print "Read line 2."

Read line 2.

Line 2: "Explicit is better than implicit."

thisis.amethod() is an explicit call to a method. If you flubbed it and
overwrote your namespace later on then you would get unexpected results at
runtime. If you remove the () it becomes an implicit call depending on the
object that is a reference to. Hmmm, I guess I could have also finished with
this line as well, "Read line 12." IE, "In the face of ambiguity, refuse the
temptation to guess."

def foo:
return 'a'

bar = foo

Is it a or is it the function object? Rats, now we have to make a special
case when point to a function as opposed to any other object. D'oh, now we
need to read line 8, "Special cases aren't special enough to break the rules."
Ok, so we shouldn't make a special case here. That also applies to where?

How often to we make calls to functions/methods without parameters
compared to how often we do? ;)

Man, I never knew that little tidbit was so fun and self referencing.
Thanks Tim Peters! :)

--
Steve C. Lamb | I'm your priest, I'm your shrink, I'm your
PGP Key: 8B6E99C5 | main connection to the switchboard of souls.
-------------------------------+---------------------------------------------
Jul 18 '05 #9

P: n/a
Roy Smith <ro*@panix.com> writes:
If the extra features [...] were really
worthwhile, they would be added to Python


Down that path lies madness (i.e. Perl).


And that's why I trust the judgement in the language developers
hands. If Ruby had enough of a "killer" feature that it would result
in flow of people from Ruby to Python, it could be added to Python.

As a whole, the py developer team seems to have their act together
better than Ruby developers, judging by the "taste" and various
perlisms in Ruby. The only thing Ruby will forever have over Python
(according to the individuals who tend to be of that opinions) is the
lack of whitespace block structure. I guess that would be the main
reason why various misguided souls choose Ruby over Python ;-).

But then again, various people choose Perl, of all things, over
Python, so I guess there doesn't need to be a rational explanation for
picking a language.

--
Ville Vainio http://www.students.tut.fi/~vainio24
Jul 18 '05 #10

P: n/a

"Bengt Richter" <bo**@oz.net> wrote in message
news:bs**********@216.39.172.122...
On Fri, 19 Dec 2003 20:22:38 -0500, "John Roth" <ne********@jhrothjr.com> wrote:

"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
news:sl*****************@dmiyu.org...
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
> a third is the ability to forget the empty parenthesis after
> a function/method call that doesn't require parameters.

class ThisIs:
avariable = 'a'
def amethod(self):
return 'b'

thisis = ThisIs()
print thisis.avariable
print thisis.amethod()
import this
print "Read line 2."


I'm not sure what your point is. Your example isn't going
to produce the expected result if you say:

print thisis.amethod

instead of

print thisis.amethod()

That is the place where I find Ruby syntax to be
helpful: the amount of time where I want the method /
function object is *far* lower than the amount of
time I want to call it. It's one of those conundrums
that doesn't seem to have a clean answer, though.

Ok, for line 2, run this ;-)

class ThisIs:
avariable = 'a'
def amethod(self):
return 'b'
def silly(self):
return 'heh'
silly = property(silly)

thisis = ThisIs()
print thisis.avariable
print thisis.amethod()
print thisis.silly
import sys
class L2(list):
def write(self, s): self.append(s)
sys.stdout = L2()
import this
L2 = ''.join(sys.stdout).splitlines()[2]
sys.stdout = sys.__stdout__
print "Read line 2."
print '... which is:', L2

Regards,
Bengt Richter


I think you're missing the point I was trying to make.
Sure, you can use a property to not have to put
in the explicit function call, but then you can't put
in the explicit function call *anywhere* you use that
property.

Ruby syntax makes it *optional*. That's what is
missing here.

John Roth
Jul 18 '05 #11

P: n/a

"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
news:sl*****************@dmiyu.org...
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
I'm not sure what your point is.
If you had run it you would have understood it. You didn't run it,

did you?
Your example isn't going to produce the expected result if you say:
print thisis.amethod

instead of

print thisis.amethod()


Well, you kind of got it. Here's the run:

Python 2.3+ (#2, Aug 10 2003, 11:33:47)
[GCC 3.3.1 (Debian)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
class ThisIs: ... avariable = 'a'
... def amethod(self):
... return 'b'
... thisis = ThisIs()
print thisis.avariable a print thisis.amethod() b import this The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those! print "Read line 2."

Read line 2.

Line 2: "Explicit is better than implicit."

thisis.amethod() is an explicit call to a method. If you flubbed it

and overwrote your namespace later on then you would get unexpected results at
runtime. If you remove the () it becomes an implicit call depending on the object that is a reference to. Hmmm, I guess I could have also finished with this line as well, "Read line 12." IE, "In the face of ambiguity, refuse the temptation to guess."

def foo:
return 'a'

bar = foo

Is it a or is it the function object? Rats, now we have to make a special case when point to a function as opposed to any other object. D'oh, now we need to read line 8, "Special cases aren't special enough to break the rules." Ok, so we shouldn't make a special case here. That also applies to where?

How often to we make calls to functions/methods without parameters
compared to how often we do? ;)

Man, I never knew that little tidbit was so fun and self referencing.
Thanks Tim Peters! :)

--
Steve C. Lamb | I'm your priest, I'm your shrink, I'm your PGP Key: 8B6E99C5 | main connection to the switchboard of souls. -------------------------------+------------------------------------------

---
Jul 18 '05 #12

P: n/a

"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
news:sl*****************@dmiyu.org...
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
I'm not sure what your point is.
If you had run it you would have understood it. You didn't run it,

did you?
It doesn't matter. As you can see by my reply to Bengt,
the crux of the issue is that, in Ruby, the function call
syntax is *optional.* There is no way to make it optional
in Python, and it is not clear whether it should be.

What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.

John Roth

--
Steve C. Lamb | I'm your priest, I'm your shrink, I'm your PGP Key: 8B6E99C5 | main connection to the switchboard of

souls.

No, you're not, and you will never be.

John Roth
Jul 18 '05 #13

P: n/a

"Ville Vainio" <vi********************@spamtut.fi> wrote in message
news:du*************@lehtori.cc.tut.fi...
"John Roth" <ne********@jhrothjr.com> writes:
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.
Doesn't this suck big time? How can the interpreter tell whether you
are trying to call a function or just want a reference to a callable
object?


That's the crux of the implementation issue, and I, for one,
haven't got an answer that doesn't look real ugly (let alone
break backwards compatability.) That's why I'm not pushing
this particular issue seriously - I don't see a way of doing it,
given the rest of Python, and completely independently of any
"Python philosophy" issues.
harder" syndrome. One of these days, someone is going
to start chewing up the user base, and for a while it looked
like Ruby might have been it.


I dunno. It just doesn't seem likely that people who have "got" Python
would switch to ruby. If the extra features of ruby were really
worthwhile, they would be added to Python (which has happened
before). I trust the Py development team to do the right decision at
all times (apart from ternary operator, obviously ;-).


The people who have switched don't post here. I'm very active
on the XP mailing list, and I see lots more references to Ruby than
to Python. Maybe the fact that such industry heavy hitters as Robert
Martin, David Thomas, and any number of others have switched
shouldn't count. In fact, the head of this thread should really be a
wakeup call: the *only* reason that Python was chosen instead
of Ruby is the lack of *current* market penetration.

As far as doing the "right" thing, check the partial list of Ruby
features I gave, and ask yourself how much each of them would
break the "feel" of Python.

It's not that the features aren't worthwhile, it's that there is a
serious philosophy issue, which I think I'm going to address in
my reply to Skip.

John Roth
--
Ville Vainio http://www.students.tut.fi/~vainio24

Jul 18 '05 #14

P: n/a
John Roth wrote:
"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
If you had run it you would have understood it. You didn't run it,
did you?
It doesn't matter. As you can see by my reply to Bengt,


It does matter, since the _output_ of the result (which Steve posted for
your convenience) contains the answer to your question.
the crux of the issue is that, in Ruby, the function call
syntax is *optional.*
The crux of this 'option' is that it's ambiguos whether you wnat to
_access_ or _call_ the function object. See line 12 of the output
meantioned above to know why Python will never implement such an
'option'. [And BTW I probably will never use a language having such an
'option'.]
What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.
*walking to the fuel-station, filling my many-years-unused flame-thrower
for the upcoming flame-battle*
John Roth


--
Regards
Hartmut Goebel

| Hartmut Goebel | We build the crazy compilers |
| h.******@crazy-compilers.com | Compiler Manufacturer |

Jul 18 '05 #15

P: n/a

"Skip Montanaro" <sk**@pobox.com> wrote in message
news:ma*************************************@pytho n.org...

John> The biggest problem is that I think Python is beginning to sucumb John> to the "we're better so we don't have to try harder" syndrome. One John> of these days, someone is going to start chewing up the user base, John> and for a while it looked like Ruby might have been it.

Can you give some concrete examples which support your contention?
I think the discussion on this thread is a reasonably good example [grin].

The responses to my comment about method calls with no
arguements should say everything that needs to be said about
attitude.

Let's skip the fluf and get to the crux. There are four languages (not
counting
minor entries) in the space Python occupies. In alphabetical order, they
are:
Perl, Python, Ruby and TCL. The originators of those languages have very
different language design philosophies.

Larry Wall (Perl): There's more than one way to do it.

Guido vanRossum (Python): There should only be one obvious way to
do anything significant.

Metz (Ruby): I want a language that's both productive and fun to program.

John Osterhout (TCL). I want a language I can embed in tools as a common
scripting language.

Notice that there is only one polarity here: Perl vs Python. Ruby goes
meta on the discussion in that it looks at what the customer (the developer)
*wants*, rather than what the language designer thinks they should have.

And *that* is the crux here. A fairly large number of people I respect
have used Python and have migrated to Ruby. For a long time, the basic
flow was from Perl to Python, for reasons that we don't need to hash over
again.

Most businesses would look at a competitor who is stealing customers
as an opportunity to figure out what those customers want that they
aren't getting.

The jihad against the "functional" builtins is a good case in point.
The replacements for apply, map and filter seem to be adequate,
and in the case of list comprehensions, pretty darned useful although
I think that it's a rather baroque addition to an otherwise very clear
and comprehensible language.

On the other hand, claiming that sum() is an adequate replacement
for reduce() is so silly that it borders on the absurd. The only
explanation I can come up with for that level of absurdity is
a desire to get rid of a feature, regardless of what it looks like.
In other words, a jihad (holy war.)

There is no replacement for lambda in sight, even though lambda is
arguably the ***largest single*** one of the functional constructs
that needs work, and has obviously needed work for a long time.

The obvious replacement for lambda, which is some form of
inline block, has not been seriously discussed, with proposed
syntax and examples, anywhere I've seen it. Clearly, I'm
not ominiscient, so that doesn't mean it hasn't, though.

The PEP 308 mess has left a rather sour taste in a lot of
people's mouths: there was a clear majority in favor of
doing *something*, but the voting was rigged (although I
doubt if it was done deliberately) to make certain that
no single proposal would get a majority.

Skip

Jul 18 '05 #16

P: n/a

"Hartmut Goebel" <h.******@crazy-compilers.com> wrote in message
news:3f***********************@newsread2.arcor-online.net...
John Roth wrote:
"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
If you had run it you would have understood it. You didn't run it,
did you?
It doesn't matter. As you can see by my reply to Bengt,


It does matter, since the _output_ of the result (which Steve posted for
your convenience) contains the answer to your question.


I've been around long enough that that level of "cute"
is simply irritating. I'm well aware of "explicit is better
than implicit."
the crux of the issue is that, in Ruby, the function call
syntax is *optional.*


The crux of this 'option' is that it's ambiguos whether you wnat to
_access_ or _call_ the function object. See line 12 of the output
meantioned above to know why Python will never implement such an
'option'. [And BTW I probably will never use a language having such an
'option'.]


And if you read the rest of my comment, you would know
that I am not suggesting that Python do so, for implementation
reasons. There are ways around the ambiguity you mention,
but they will not come out unless there is a *thoughtful*
discussion, and in any case they would definitely break
backwards compatability.
> What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.


*walking to the fuel-station, filling my many-years-unused flame-thrower
for the upcoming flame-battle*


Why bother?

John Roth
John Roth


--
Regards
Hartmut Goebel

| Hartmut Goebel | We build the crazy compilers |
| h.******@crazy-compilers.com | Compiler Manufacturer |

Jul 18 '05 #17

P: n/a
"John Roth" <ne********@jhrothjr.com> writes:
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.
Doesn't this suck big time? How can the interpreter tell whether you
are trying to call a function or just want a reference to a callable
object?
That's the crux of the implementation issue, and I, for one,
haven't got an answer that doesn't look real ugly (let alone
break backwards compatability.) That's why I'm not pushing
this particular issue seriously - I don't see a way of doing it,
given the rest of Python, and completely independently of any
"Python philosophy" issues.
Most importantly, why would anyone even care? Ability to optionally
invoke a "call" operation on an object implicitly seems utterly
worthless to me. It has the feel of perl philosophy (regexps in
language syntaxm anyone? ), and it's not the only instance in Ruby. I
don't really like the Perl philosophy (like most of the people who
"get" Python), and I don't really believe a language whose designers
appreciate the perlisms poses a serious threat to Python. Not even if
they got some things right.
to Python. Maybe the fact that such industry heavy hitters as Robert
Martin, David Thomas, and any number of others have switched
Frankly, I don't know who these "heavy hitters" are, but they probably
have their reasons. Quick googling didn't turn out any useful articles
explaining why either of them has switched from Python to Ruby.
As far as doing the "right" thing, check the partial list of Ruby
features I gave, and ask yourself how much each of them would
break the "feel" of Python.


I am yet to see a feature list that would inspire me to switch, or
even consider switching. The little advantages Ruby has over Python
are dwarfed by the advantages of Python (of which the least is not
maturity, community and documentation).

--
Ville Vainio http://www.students.tut.fi/~vainio24
Jul 18 '05 #18

P: n/a

"Ville Vainio" <vi********************@spamtut.fi> wrote in message
news:du*************@mozart.cc.tut.fi...
"John Roth" <ne********@jhrothjr.com> writes:
> a third is the ability to forget the empty parenthesis after
> a function/method call that doesn't require parameters. Doesn't this suck big time? How can the interpreter tell whether you
are trying to call a function or just want a reference to a callable
object?
That's the crux of the implementation issue, and I, for one,
haven't got an answer that doesn't look real ugly (let alone
break backwards compatability.) That's why I'm not pushing
this particular issue seriously - I don't see a way of doing it,
given the rest of Python, and completely independently of any
"Python philosophy" issues.
Most importantly, why would anyone even care? Ability to optionally
invoke a "call" operation on an object implicitly seems utterly
worthless to me.


That may not be one of your common coding mistakes.
My mind doesn't quite get the point of inserting an
otherwise useless pair of parenthesis, and consequently
it's fairly high on the list of common coding errors I make
that causes run time errors. Of course, rigidly applying
TDD will bring those errors up rapidly so they don't
lurk to cause problems later, but not having them in the
first place would be even better.

There's a Japanese term used in Lean Manufacturing
that basically translates as "mistake proofing." While
Python makes it harder to make mistakes than many
other languages, it is certainly not perfect in that respect,
and this issue is one of several that fall into that category.
It has the feel of perl philosophy (regexps in
language syntaxm anyone? ), and it's not the only instance in Ruby. I
don't really like the Perl philosophy (like most of the people who
"get" Python), and I don't really believe a language whose designers
appreciate the perlisms poses a serious threat to Python. Not even if
they got some things right.
I suspect you're missing the point. I'm not advocating Ruby,
which has, as far as I am concerned, enough problems that
I'm not considering shifting at this time. What I am advocating
is looking at what it's doing right and asking if some of those
things might not improve Python.
to Python. Maybe the fact that such industry heavy hitters as Robert
Martin, David Thomas, and any number of others have switched


Frankly, I don't know who these "heavy hitters" are, but they probably
have their reasons. Quick googling didn't turn out any useful articles
explaining why either of them has switched from Python to Ruby.


Let's see. Dave (the Pragmatic Programmer) wrote the textbook on
Ruby, and I think his preface says it quite nicely.
As far as doing the "right" thing, check the partial list of Ruby
features I gave, and ask yourself how much each of them would
break the "feel" of Python.


I am yet to see a feature list that would inspire me to switch, or
even consider switching. The little advantages Ruby has over Python
are dwarfed by the advantages of Python (of which the least is not
maturity, community and documentation).


As I said, my intent is not to inspire anyone to switch. My intent
is to ask whether there is anything they're doing that would be
(in concept if not in implementation) an improvement to Python.

John Roth
--
Ville Vainio http://www.students.tut.fi/~vainio24

Jul 18 '05 #19

P: n/a
On Fri, Dec 19, 2003 at 07:29:57PM -0500, John Roth wrote:
"Ville Vainio" <vi********************@spamtut.fi> wrote in message
news:du*************@amadeus.cc.tut.fi...
I don't know if you have seen this before, but here goes:

http://text.userlinux.com/white_paper.html

There is a jab at Python, though, mentioning that Ruby is more
"refined".


I'm not sure about refined, but it does seem to have several
things that I think I'd like. One is a much
better way of handling anonymous functions, aka "blocks."
Another is the pervasive use of the visitor pattern, and


I've always considered the visitor pattern as a rather poor substitute
for generators, not as a something worth having for its own sake. Using
generators instead of visitors+anonymous functions obviously reduces the
need for anonymous functions (not that it's any excuse for not having
something better than Python's lambdas!).

Oren

Jul 18 '05 #20

P: n/a
In article <vu***********@news.supernews.com>,
John Roth <ne********@jhrothjr.com> wrote:

The people who have switched don't post here. I'm very active
on the XP mailing list, and I see lots more references to Ruby than
to Python. Maybe the fact that such industry heavy hitters as Robert
Martin, David Thomas, and any number of others have switched
shouldn't count. In fact, the head of this thread should really be a
wakeup call: the *only* reason that Python was chosen instead
of Ruby is the lack of *current* market penetration.


AFAIK, those are all people who were never heavy Python users. We're
still getting plenty of people switching to Python instead of Ruby,
largely because there are more killer applications written in Python.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Weinberg's Second Law: If builders built buildings the way programmers wrote
programs, then the first woodpecker that came along would destroy civilization.
Jul 18 '05 #21

P: n/a

"Oren Tirosh" <or*******@hishome.net> wrote in message
news:ma*************************************@pytho n.org...
On Fri, Dec 19, 2003 at 07:29:57PM -0500, John Roth wrote:
"Ville Vainio" <vi********************@spamtut.fi> wrote in message
news:du*************@amadeus.cc.tut.fi...
I don't know if you have seen this before, but here goes:

http://text.userlinux.com/white_paper.html

There is a jab at Python, though, mentioning that Ruby is more
"refined".
I'm not sure about refined, but it does seem to have several
things that I think I'd like. One is a much
better way of handling anonymous functions, aka "blocks."
Another is the pervasive use of the visitor pattern, and


I've always considered the visitor pattern as a rather poor substitute
for generators, not as a something worth having for its own sake. Using
generators instead of visitors+anonymous functions obviously reduces the
need for anonymous functions (not that it's any excuse for not having
something better than Python's lambdas!).


I'm not certain I'm making the connection. The visitor pattern
as I use it doesn't seem to have much to do with generators.
It's a way of disconnecting the sequencing logic from the
processing logic, while a generator seems to encapsulate
both in the same function.

A good case in point is file processing. I've got a class that
encapsulates a directory: instantiate it and it reads the directory
into an internal list. Then if you invoke the .visit(instance)) method,
it calls either the 'file' or the 'directory' method in that instance
for each of the names in the directory. If I need to go down a
directory chain, I simply invoke it recursively.

If I arranged it so I called the visitor instance one last time
(possibly using a 'lastTime' method) I could completely
replace the reduce built-in for any object that had a .visit
method!

Blocks plus the pervasive availibility of a .visit() method is the
overwhelmingly most common thing Ruby users mention for
why they like the language. It seems to be somewhat of a
paradigm shift.

John Roth
Oren

Jul 18 '05 #22

P: n/a
In article <vu***********@news.supernews.com>, John Roth wrote:
to Python. Maybe the fact that such industry heavy hitters as Robert
Martin, David Thomas, and any number of others have switched
shouldn't count. In fact, the head of this thread should really be a


I think this has a lot to do with Ruby's greater similarity to Smalltalk.

Dave Cook
Jul 18 '05 #23

P: n/a

John> The biggest problem is that I think Python is beginning to sucumb
John> to the "we're better so we don't have to try harder" syndrome.
John> One of these days, someone is going to start chewing up the user
John> base, and for a while it looked like Ruby might have been it.
Can you give some concrete examples which support your contention?


John> I think the discussion on this thread is a reasonably good example
John> [grin].

John> The responses to my comment about method calls with no arguements
John> should say everything that needs to be said about attitude.

Not really. You're holding this discussion on comp.lang.python, not on
py********@python.org. I interpreted your statement about not having to
"try harder" as being aimed at the people who work on the language and the
standard library. Perhaps I was mistaken. In any case, I don't see it as
necessarily a bad thing that there are multiple languages out there with
overlapping features and audiences. They absorb some ideas but not others,
and when they do they don't absorb them in precisely the same way. You can
interpret that as not trying harder, but I don't.

Python's design doesn't admit the option of calling functions without the
parens. Perl's and Ruby's do. On the other hand, functions are first-class
objects in Python. I don't know about Ruby, but in Perl, whether or not a
function is called or treated as a piece of data is very context-dependent,
to the point of near madness for people like myself who don't use it day in
and day out.

John> Let's skip the fluf and get to the crux. There are four languages
John> (not counting minor entries) in the space Python occupies.

John> Larry Wall (Perl): There's more than one way to do it.

John> Guido vanRossum (Python): There should only be one obvious way to
John> do anything significant.

John> Metz (Ruby): I want a language that's both productive and fun to
John> program.

John> John Osterhout (TCL). I want a language I can embed in tools as a
John> common scripting language.

John> Notice that there is only one polarity here: Perl vs Python. Ruby
John> goes meta on the discussion in that it looks at what the customer
John> (the developer) *wants*, rather than what the language designer
John> thinks they should have.

Different design philosophies result in different languages. That's to be
expected. If Ruby floats your boat, use it. Advocate for it if you like,
but don't expect that because you like Ruby's philosophy better that Python
necessarily ought to move in that direction. I happen to think Python is
both productive and fun to use. But that's just me.

John> Most businesses would look at a competitor who is stealing
John> customers as an opportunity to figure out what those customers
John> want that they aren't getting.

Who's stealing customers? This is open source. We have no shareholders or
board of directors to appease. We scratch our own itches. If Ruby relieves
itching for more people than Python, so be it. Nobody's going to go out of
business because of it.

John> The jihad against the "functional" builtins is a good case in
John> point. The replacements for apply, map and filter seem to be
John> adequate, and in the case of list comprehensions, pretty darned
John> useful although I think that it's a rather baroque addition to an
John> otherwise very clear and comprehensible language.

Why do you call it a "jihad"? Guido has stated on multiple occasions that
he regretted adding functional constructs to the language. I still can't
get to the Python website (have to wait another two hours for my ISP to
reload its tables), but here's a Google pointer to an HTML-ized version of
his OSCON 2002 Powerpoint slides:

http://216.239.41.104/search?q=cache...hl=en&ie=UTF-8

John> On the other hand, claiming that sum() is an adequate replacement
John> for reduce() is so silly that it borders on the absurd.

No, operationally that's a correct statement. People have looked at the use
of reduce() in a number of different contexts. In all but the rarest of
cases, reduce() was used to sum a list of numbers. sum() is a perfectly
adequate replacement in all but those rare cases and is easier to read as
well. As Guido mentioned in the talk I referenced above:

reduce()
nobody uses it, few understand it
a for loop is clearer & (usually) faster

John> The only explanation I can come up with for that level of
John> absurdity is a desire to get rid of a feature, regardless of what
John> it looks like. In other words, a jihad (holy war.)

No, it's simply not used very much. Python never has been a very strong
functional language. It's always been a very strong object-oriented
language. Use it the way it's strongest.

John> There is no replacement for lambda in sight, even though lambda is
John> arguably the ***largest single*** one of the functional constructs
John> that needs work, and has obviously needed work for a long time.

Once again, you desire Python to be something it is not. If you want a
strong functional language, program in Lisp or Haskell.

John> The obvious replacement for lambda, which is some form of inline
John> block, has not been seriously discussed, with proposed syntax and
John> examples, anywhere I've seen it. Clearly, I'm not ominiscient, so
John> that doesn't mean it hasn't, though.

Anonymous blocks are not a replacement for lambdas, named functions are.
How do you pass parameters to an anonymous block?

John> The PEP 308 mess has left a rather sour taste in a lot of people's
John> mouths: there was a clear majority in favor of doing *something*,
John> but the voting was rigged (although I doubt if it was done
John> deliberately) to make certain that no single proposal would get a
John> majority.

Again, it's something that doesn't fit easily into Python's design. There
were several ternary operator proposals advanced, but none was a clear
winner. Guido's a conservative language designer for the most part. It's
better to leave it out than to put something in you'll regret later. PEP
308 wasn't the first time the ternary operator discussion has come up, by
the way. Functional programming, ternary operators, anonymous code blocks.
They've all been issues for a long time.

You seem to have a burr under your saddle about this stuff. I'm not sure
why. Maybe it's time to get out the curry comb...

Skip

Jul 18 '05 #24

P: n/a
On Sat, Dec 20, 2003 at 08:44:45AM -0500, John Roth wrote:
I'm not certain I'm making the connection. The visitor pattern
as I use it doesn't seem to have much to do with generators.
It's a way of disconnecting the sequencing logic from the
processing logic,
You mean like this?

def generator(...):
sequencing logic, yield stuff

for object in generator(...):
processing logic
while a generator seems to encapsulate both in the same function.
Can you give any specific reasons why you believe this to be the
case?
A good case in point is file processing. I've got a class that
encapsulates a directory: instantiate it and it reads the directory
into an internal list. Then if you invoke the .visit(instance)) method,
it calls either the 'file' or the 'directory' method in that instance
for each of the names in the directory. If I need to go down a
directory chain, I simply invoke it recursively.
Recursively? I thought the whole point of using such a class was to
disconnect, as you say, the sequencing logic from the processing logic.
If the user of the class must explicitly invoke the recursion the
sequencing logic becomes hard-wired into the processing logic. With a
generator you could pass an argument to the sequence logic that instructs
it to do, for example, a breadth-first or depth-first traversal without
affecting the processing logic.
If I arranged it so I called the visitor instance one last time
(possibly using a 'lastTime' method) I could completely


Like this?

for object in generator(...):
processing logic
last time
I think it's great that Python has functions and bound methods as
first-class objects and that they can be passed around as values. I just
don't think they should be used when there are far simpler ways to
achieve the same result.

Oren

Jul 18 '05 #25

P: n/a
"John Roth" <ne********@jhrothjr.com> writes:
Notice that there is only one polarity here: Perl vs Python. Ruby goes
meta on the discussion in that it looks at what the customer (the developer)
*wants*, rather than what the language designer thinks they should have.
Customer is often less informed than the language designer. I think
someone mentioned somewhere that Perl is a "popularity whore", I guess
the same applies to Ruby. I can rest assured that Python won't start
decaying because the language designers wanted to please the whims of
some members of the audience.
Most businesses would look at a competitor who is stealing customers
as an opportunity to figure out what those customers want that they
aren't getting.
Fair enough. Someone might want to compile a list where the issue
could be dissected once and for all. A lot of the issues rubyists have
tend to be along the lines of "well, Python has this feature *now*,
but it wasn't in version blah blah when I tried it. We had it since
the beginning, so it is not an add-on but a real feature!". IOW, they
fall apart w/ even a minor analysis.
and in the case of list comprehensions, pretty darned useful although
I think that it's a rather baroque addition to an otherwise very clear
and comprehensible language.
List comprehensions are, for me, one of the killer features in Python
that raise Python above all other languages (Haskell has them, but
it's.. umm.. Haskell and one would be laughed out of the office if he
suggested Haskell for implementing anything).
There is no replacement for lambda in sight, even though lambda is
arguably the ***largest single*** one of the functional constructs
that needs work, and has obviously needed work for a long time.


Party line is that ppl should just define a function with a name. It
might not be the most comfortable option at the time of writing the
code, but it will make the program more readable. It is definitely not
a big enough of a problem to switch the language.

Hmm, I wonder if it is the time to start crossposting this to c.l.ruby
and let the flamewar start. It's been a while already ;-).

--
Ville Vainio http://www.students.tut.fi/~vainio24
Jul 18 '05 #26

P: n/a
"John Roth" <ne********@jhrothjr.com> wrote...
What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.


The point he was making (in a rather convoluted way) is that optional
parens is against the Python philosophy. "Explicit rather than
implicit" being line 2. I would rather be forced to use empty parens
after a function call - it shows you/others exactly what you are
trying to do.

On the other hand, I would detest Python if by simply referring to an
object with a __call__ method caused it to be executed. I'd say that's
closer to braindead.

a = sys.exit
a

Unless you design some silly rules to determine when empty parenthesis
should be allowed - did a get assigned the return value of sys.exit()?
(yes I know it doesn't have one), or did some silly unclear
(implicit) rules stop that from happening. Did sys.exit() run on the
second line?

I think if you can't understand why this option isn't provided for
you, then you misunderstand some of the most fundamental Python
concepts. import this.
David.
Jul 18 '05 #27

P: n/a
"John Roth" <ne********@jhrothjr.com> wrote in message
news:vu************@news.supernews.com...
a third is the ability to forget the empty parenthesis after
a function/method call that doesn't require parameters.


Hi.
Every time I see that feature in Ruby I find it appealing - and then I don't
(which is kind of how I feel about the language as a whole). I find it
appealing because, well, like you've said, the operation doesn't require
parameters, so why clutter up the code with unnecessary parenthesis? And if
I only ever read my own code, and I was sure I would always know what I had
been doing in older code, I might be okay using that feature. But that's not
the case. I do have to read other people's code, which means (in this case)
I have to decipher, on each occurrence of

a

whether that is a variable or an implicit operation call (if I care about
that sort of thing, which I might). In Python, it's a binding (unless it's a
property "obj.a" in which case it's still a binding to a descriptor but that
gets invoked during look-up, so ... have I lost my leg to stand on there?).

I suppose I just prefer to know, from reading that line of code, without
tracking back into other parts of the implementation, or running it to find
out, whether a is a variable or an operation. But, then, properties can
obscure the issue in Python just as well, so I don't think this argument has
much steam (unless I advocate losing properties - which I really don't).

So, I'll address a slightly different but wholly related issue. In Python,
when I want to pass a function, method, or object as an argument, I do so by
name:

callable(function, method, obj)

The names in the argument list are bindings to the object - in this case to
a function, a method and some other type of object. Using the name of a
function or method does not invoke it, so I can pass these operations by
name without resorting to disambiguatory syntax introduction. Not so in
Ruby: because, there, the names function/method would be found (during
lookup) to refer to callables that take no parameters, so Ruby would invoke
them - which is not what we want. To get around this, Ruby introduces
:function, :method - which is not so terrible, I suppose. It's a trade-off
imposed, in part, by the desire of the language designer to allow for a
cleaner parameter-less method invocation. So, they've cleaned up one thing,
only to dirty up another. And Python has done the same thing, only they've
cleaned up name referencing rather than parameter-less callable invocations.

Which is better? Having to say a() explicitly when you wish to invoke a
callable, or having to say :a when you wish only to refer to the object and
not invoke it? Well, If we just go by syntax, :a uses one less character
than a(), so that could be a plus. And :a is very explicit (once you know
what it means) - you know you're using a name reference (correct term?).
But, when a and a() can both mean the same thing, or different things,
depending on the context ...

a = "variable"

def a
"method"
end

puts a
puts a()

# output
variable
method
... well, for me, that's not such a great thing.

Part of language design appears to be about trade-off. And part of language
preference appears to be about choosing the language that handles most of
those tradeoffs as you would prefer (which can save you from having to write
your own). I think I prefer that callable invocation be done explicitly, so
that I may recognize it as such in my, and other people's, code. And I think
I prefer not having to disambiguate name referencing via arbitrary syntax. I
think that's what I prefer - and yet I see the allure of the "Ruby Way".

Why use parenthesis for an empty parameter-list, when you don't have to? To
be explicit. Why is that preferable? Because it's explicit? Um. Try again.
Because explicit is better than implicit? Begs the question. Because
ambiguous code requires you to expend more time reading to understand than
does less ambiguous code? Hm. I don't find the code ambiguous, but even so
the ambiguous code might take less time to write, so the overall time may
balance out. People read code more often than they write it, so the balance
would tip towards those who must read the code. Do they? Prove it. I site
such and such a study. Well, I write more code than I read. Then you musn't
be a very good programmer... and how could you write more code than you
read? Do you not read your own code? You know what I meant, and who're you
calling a bad programmer? ...

And so on ... ad nauseum ... much like this post ... heh

Sean


Jul 18 '05 #28

P: n/a
"John Roth" <ne********@jhrothjr.com> writes:
Most importantly, why would anyone even care? Ability to optionally
invoke a "call" operation on an object implicitly seems utterly
worthless to me.
That may not be one of your common coding mistakes.


It was when I started. Not after a while.
My mind doesn't quite get the point of inserting an
otherwise useless pair of parenthesis, and consequently
it's fairly high on the list of common coding errors I make
that causes run time errors. Of course, rigidly applying
Don't something like pychecker detect these things?
TDD will bring those errors up rapidly so they don't
lurk to cause problems later, but not having them in the
first place would be even better.
Not if they go against the fundamental ideas of how the language
works.

is looking at what it's doing right and asking if some of those
things might not improve Python.
Hasn't Alex Martelli done something like this recently? Alex?
As I said, my intent is not to inspire anyone to switch. My intent
is to ask whether there is anything they're doing that would be
(in concept if not in implementation) an improvement to Python.


Sounds like a morally correct motive :-).

--
Ville Vainio http://www.students.tut.fi/~vainio24
Jul 18 '05 #29

P: n/a

"David M. Wilson" <dw***********@botanicus.net> wrote in message
news:99**************************@posting.google.c om...
"John Roth" <ne********@jhrothjr.com> wrote...
What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.
The point he was making (in a rather convoluted way) is that optional
parens is against the Python philosophy. "Explicit rather than
implicit" being line 2. I would rather be forced to use empty parens
after a function call - it shows you/others exactly what you are
trying to do.

On the other hand, I would detest Python if by simply referring to an
object with a __call__ method caused it to be executed. I'd say that's
closer to braindead.

a = sys.exit
a

Unless you design some silly rules to determine when empty parenthesis
should be allowed - did a get assigned the return value of sys.exit()?
(yes I know it doesn't have one), or did some silly unclear
(implicit) rules stop that from happening. Did sys.exit() run on the
second line?

I think if you can't understand why this option isn't provided for
you, then you misunderstand some of the most fundamental Python
concepts. import this.


I don't think I misunderstand it. As I've said several times in this
thread, I am not seriously advocating it for a number of reasons.

However, yours is not one of them. It's easy enough to distinguish
between a function and some other kind of object that simply has
a __call__ method. Functions provide the number of parameters
they are expecting, other callables don't, so it would indeed be
brain dead to expect an absent call parameter to call something
other than a function. Also, to make it crystal clear, to call anything
other than a function that is expecting no parameters.

Please think before making a critique.

John Roth

David.

Jul 18 '05 #30

P: n/a

"Ville Vainio" <vi********************@spamtut.fi> wrote in message
news:du*************@amadeus.cc.tut.fi...
"John Roth" <ne********@jhrothjr.com> writes:
Most importantly, why would anyone even care? Ability to optionally
invoke a "call" operation on an object implicitly seems utterly
worthless to me.


That may not be one of your common coding mistakes.


It was when I started. Not after a while.
My mind doesn't quite get the point of inserting an
otherwise useless pair of parenthesis, and consequently
it's fairly high on the list of common coding errors I make
that causes run time errors. Of course, rigidly applying


Don't something like pychecker detect these things?


Since I normally use TDD, using Pychecker would slow
the flow down substantially. See the next paragraph.
TDD will bring those errors up rapidly so they don't
lurk to cause problems later, but not having them in the
first place would be even better.


Not if they go against the fundamental ideas of how the language
works.


If a language makes opportunities for errors, then there is
something wrong with the language that needs to be corrected.
I'm not a fan of carrying a reasonable idea past the point where
it starts showing its flaws. I'm also not a fan of the idea that
there are any ideas that are flawless if carried to extreme.
is looking at what it's doing right and asking if some of those
things might not improve Python.


Hasn't Alex Martelli done something like this recently? Alex?


There was a mini-project to identify "warts" a year or two ago.
Is this what you mean?
As I said, my intent is not to inspire anyone to switch. My intent
is to ask whether there is anything they're doing that would be
(in concept if not in implementation) an improvement to Python.


Sounds like a morally correct motive :-).

--
Ville Vainio http://www.students.tut.fi/~vainio24


John Roth
Jul 18 '05 #31

P: n/a
Oren Tirosh <or*******@hishome.net> writes:
I've always considered the visitor pattern as a rather poor substitute
for generators, not as a something worth having for its own sake. Using
generators instead of visitors+anonymous functions obviously reduces the
need for anonymous functions (not that it's any excuse for not having
something better than Python's lambdas!).


This is a bit out of context, as I've not read the full thread here,
but while I can see that the visitor pattern doesn't offer anything
much over generators for a *single* visitor function, I'm not sure how
that generalises to visitors with multiple "visit" methods.

Consider a file-tree walker, which takes a visitor. On each directory
seen, the visit_directory() method is called, on each file seen, the
visit_file() method is called, and on each symlink seen, the
visit_symlink() method is called.

Replacing that with generators seems like it may be clumsy. Or have I
missed a simple transformation?

Paul.
--
This signature intentionally left blank
Jul 18 '05 #32

P: n/a
Ville Vainio <vi********************@spamtut.fi> wrote...
I don't know if you have seen this before, but here goes:

http://text.userlinux.com/white_paper.html

There is a jab at Python, though, mentioning that Ruby is more
"refined".

I read a lot of that last night, and I find it intriguing. It strikes
me as being misdirected on a number of fronts, but that's Linux talk
so I'll skip it here.

I find his rationale for using Python to be poor. It is lumped between
two bullets for 'Mail Transfer Agent' and 'Java-like environment'. His
reasoning for using Python is terse - essentially because he couldn't
use Ruby.

Maybe he was typing this up in a rush, but regardless. The reasons he
has given for making Python the primary 'interpretive'(wtf?) language
are unclear. I could think of a hundred reasons for it, but that's not
my job, it's his.

I wouldn't call what he said a jibe, given that he shows no
understanding of what Python is about. If he isn't or hasn't been an
enlightened one, then how can he insult us? :)
David.
Jul 18 '05 #33

P: n/a

"Skip Montanaro" <sk**@pobox.com> wrote in message
news:ma*************************************@pytho n.org...


Python's design doesn't admit the option of calling functions without the
parens. Perl's and Ruby's do. On the other hand, functions are first-class objects in Python. I don't know about Ruby, but in Perl, whether or not a
function is called or treated as a piece of data is very context-dependent, to the point of near madness for people like myself who don't use it day in and day out.
That's one of the reasons it was a rather bad choice of example.
As far as I can tell, it would be quite hard to do in any comprehensible
fashion, and not backward compatible.

John> The jihad against the "functional" builtins is a good case in
John> point. The replacements for apply, map and filter seem to be
John> adequate, and in the case of list comprehensions, pretty darned
John> useful although I think that it's a rather baroque addition to an John> otherwise very clear and comprehensible language.

Why do you call it a "jihad"? Guido has stated on multiple occasions that
he regretted adding functional constructs to the language. I still can't
get to the Python website (have to wait another two hours for my ISP to
reload its tables), but here's a Google pointer to an HTML-ized version of
his OSCON 2002 Powerpoint slides:

http://216.239.41.104/search?q=cache...hl=en&ie=UTF-8

I've read it before. I'm in complete agreement that the replacement
for apply makes the lanugage cleaner, and I've no particular objection
to list comprehensions replacing map and filter.
John> There is no replacement for lambda in sight, even though lambda is John> arguably the ***largest single*** one of the functional constructs John> that needs work, and has obviously needed work for a long time.

Once again, you desire Python to be something it is not. If you want a
strong functional language, program in Lisp or Haskell.

John> The obvious replacement for lambda, which is some form of inline
John> block, has not been seriously discussed, with proposed syntax and John> examples, anywhere I've seen it. Clearly, I'm not ominiscient, so John> that doesn't mean it hasn't, though.

Anonymous blocks are not a replacement for lambdas, named functions are.
How do you pass parameters to an anonymous block?
By putting them in the first line. Again, I'm not a language purist, and
if the term 'block' means something to someone that causes confusion,
then I regret it.

Frankly, I don't think that anyone is going to come up with the ideal
syntax for anonymous functions. The thing that becomes more and
more apparent every time I think of it is that one of Python's real
strengths,
it's automatic indentation, also makes it very hard to incorporate statement
syntax within expressions.
You seem to have a burr under your saddle about this stuff. I'm not sure
why. Maybe it's time to get out the curry comb.
The world changes, and ideas that seemed to be perfectly appropriate
five or ten years ago may no longer be such. Small languages with a limited
audience have a perfect right to be as quirky or as "pure" as their authors
want. Once they get beyond that point, there's a bit of social
responsibility
involved in addressing common problems.

John Roth
Skip

Jul 18 '05 #34

P: n/a

"Oren Tirosh" <or*******@hishome.net> wrote in message
news:ma*************************************@pytho n.org...
On Sat, Dec 20, 2003 at 08:44:45AM -0500, John Roth wrote:
I'm not certain I'm making the connection. The visitor pattern
as I use it doesn't seem to have much to do with generators.
It's a way of disconnecting the sequencing logic from the
processing logic,
You mean like this?

def generator(...):
sequencing logic, yield stuff

for object in generator(...):
processing logic


Good point. That's upside down from the way I usually
think of it.
while a generator seems to encapsulate both in the same function.
Can you give any specific reasons why you believe this to be the
case?


Yes. You now have two sequencing constructs: the for loop
and the loop inside the generator. The visitor pattern has only
one: the for loop inside the .visit() method.

John Roth


Oren

Jul 18 '05 #35

P: n/a
David M. Wilson <dw***********@botanicus.net> pisze:
Unless you design some silly rules to determine when empty parenthesis
should be allowed - did a get assigned the return value of sys.exit()?
(yes I know it doesn't have one)


It has. The returned value is None.

--
Jarek Zgoda
Unregistered Linux User # -1
http://www.zgoda.biz/ JID:zg***@chrome.pl http://zgoda.jogger.pl/
Jul 18 '05 #36

P: n/a
Ville Vainio wrote:
Most importantly, why would anyone even care? Ability to optionally
invoke a "call" operation on an object implicitly seems utterly
worthless to me. It has the feel of perl philosophy (regexps in
language syntaxm anyone? ), and it's not the only instance in Ruby. I
don't really like the Perl philosophy (like most of the people who
"get" Python), and I don't really believe a language whose designers
appreciate the perlisms poses a serious threat to Python. Not even if
they got some things right.


Hmm, I looked at Ruby a few months ago, and while it has more similarities to
Python than differences, its design philosophies are indeed very different. As
such, it seems less "clean" to me than Python (but anyone's MMV, of course).
In some places it seems too "pure", in other places it adds a lot of extra
syntax for special cases. It's just different from Python, but I expect that
many people don't care much about that.

The rise of Ruby may not be a good thing for Python, but I think that in the
long run, it's good for scripting/dynamic languages as a whole. Python gets
another competitor, which wouldn't be possible if dynamic (agile?) languages
were not a viable choice. Enough people are interested in dynamic languages
that there's room for another one. So, in a way, it's a sign that people who
use one of these languages (be it Python, Perl, Ruby) are on the right track.

As for switching... I like Ruby's code blocks (although not necessarily the way
they are used), and maybe a few other small things, but I haven't seen anything
that would make me seriously consider switching.

--
Hans (ha**@zephyrfalcon.org)
http://zephyrfalcon.org/

Jul 18 '05 #37

P: n/a
John Roth fed this fish to the penguins on Saturday 20 December 2003
04:19 am:


John Osterhout (TCL). I want a language I can embed in tools as a
common scripting language.
Given that last entry, I'll speak blasphemy since I feel there is a
fifth candidate. REXX, especially as implemented on the Amiga, /was/
such a common scripting language without needing to be "embedded"
within the application/tool (it actually was done in a way that
permitted one script to glue multiple "tools" together).
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #38

P: n/a

"Dennis Lee Bieber" <wl*****@ix.netcom.com> wrote in message
news:2r************@beastie.ix.netcom.com...
John Roth fed this fish to the penguins on Saturday 20 December 2003
04:19 am:


John Osterhout (TCL). I want a language I can embed in tools as a
common scripting language.
Given that last entry, I'll speak blasphemy since I feel there is

a fifth candidate. REXX, especially as implemented on the Amiga, /was/
such a common scripting language without needing to be "embedded"
within the application/tool (it actually was done in a way that
permitted one script to glue multiple "tools" together).


Oh, there were a lot of those languages, but that was what
Osterhout wanted for TCL - something that could be embedded
in various tools. He had a problem, and it was lots of tools, each
of which used its own special purpose, completely incompatible
and usually poorly implemented language.

REXX was very much a niche specific language, mostly on
IBM systems (because IBM also wanted to consolidate
languages.) It grew beyond there, but not by all that much.
Part of it's quirky charm is the way that it's i/o system faithfully
mirrored the old VM/CMS system.

John Roth

============================================= <
> wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
> wu******@dm.net | Bestiaria Support Staff <
> ================================================== ============ <
> Bestiaria Home Page: http://www.beastie.dm.net/ <
> Home Page: http://www.dm.net/~wulfraed/ <

Jul 18 '05 #39

P: n/a
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
It doesn't matter. As you can see by my reply to Bengt,
the crux of the issue is that, in Ruby, the function call
syntax is *optional.* There is no way to make it optional
in Python, and it is not clear whether it should be.
It is quite clear. I, and others, have shown why several times.
What I'm missing, however, is any *thoughtful*
discussion of the issues involved. Your [perjoritive
adverb deleted] response makes it clear that you
didn't think of the issues, you just reacted.


No, I didn't react and I have thought. Want to know my thinking? 5+
years of programming Perl professionally and being damned tired of trying to
debug not only other people's code but even *my own code* which I wrote before
I restricted myself to using as few implicit calls as I could get away with.
I've gone on to argue against main implicit calls in various different
languages in several different venues (here, Debian lists, in the workplace,
in private discussions, etc) and provided examples why the ambiguity sets up
the programmer, the program and the maintainer for problems down the road.

Now just because you weren't around to see all of this or be in on any of
it doesn't mean it didn't happen. Furthermore it also does not mean that
every time some neophyte comes in throwing languages wishes which have been
discussed at great length several times before that we have to engage in the
same weeks long discussion AGAIN just for his sole benefit! No, we give
concise examples on why that position is the way it is.

That's what you got. You chose to ignore it. Instead of engaging in the
valid points present you ignored them and flamed me. Bravo, way to get your
point across. So until you can address these points I strongly suggest you
not reply because the chances of you making any serious headway without
addressing them is on you. Great thought HAS been put into them. So far no
thought has apparently been put in your position.

1: Calling a function or method without parameters occurs far, far less than
calling a function or method with parameters. This constitutes a special
case.

2: Making the calling syntax optional creates ambiguity because one does not
know if we're making an assignment to the function/method object or an
assignment to the results of the function/method.

3: Making the calling syntax optional creates ambiguity for the maintainer
since it muddles the visual difference between variables and function/method
names.

4: Making the calling syntax optional dictates that to maintain functionality
additional syntax need be created to address the case where one wants to
assign to a function/method ojbect and not to the return of said object.

5: In doing all of the above we have now introduced multiple ways to do the
same thing on 2 different occasions.

The onus is on you to explain, given these statements that we Python
programmers tend to like to adhere to...

Explicit is better than implicit.
Simple is better than complex.
Special cases aren't special enough to break the rules.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.

...why the behavior is desireable when it is implicit, complex guess on a
special case that introduces an additional way to do something which combined
means the language is harder to read and maintian all so you can save two
whole shifted keystrokes.

--
Steve C. Lamb | I'm your priest, I'm your shrink, I'm your
PGP Key: 8B6E99C5 | main connection to the switchboard of souls.
-------------------------------+---------------------------------------------
Jul 18 '05 #40

P: n/a
On 2003-12-20, Roy Smith <ro*@panix.com> wrote:
Ville Vainio <vi********************@spamtut.fi> wrote:
If the extra features [...] were really
worthwhile, they would be added to Python
Down that path lies madness (i.e. Perl).


Nono, that's not the quote!
YODA: Code! Yes. A programmer's strength flows from code
maintainability. But beware of Perl. Terse syntax... more than
one way to do it...default variables. The dark side of code
maintainability are they. Easily they flow, quick to join you
when code you write. If once you start down the dark path,
forever will it dominate your destiny, consume you it will.
--
Steve C. Lamb | I'm your priest, I'm your shrink, I'm your
PGP Key: 8B6E99C5 | main connection to the switchboard of souls.
-------------------------------+---------------------------------------------
Jul 18 '05 #41

P: n/a

"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
news:sl*****************@dmiyu.org...
On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
It doesn't matter. As you can see by my reply to Bengt,
the crux of the issue is that, in Ruby, the function call
syntax is *optional.* There is no way to make it optional
in Python, and it is not clear whether it should be.
It is quite clear. I, and others, have shown why several times.


It's clear that it should be? No, that's clearly not what
you meant.

Remainder of rant snipped.

John Roth
--
Steve C. Lamb | I'm your priest, I'm your shrink, I'm your PGP Key: 8B6E99C5 | main connection to the switchboard of

souls.

As I said before, you are not and will never be.
Jul 18 '05 #42

P: n/a
On Sat, Dec 20, 2003 at 08:01:05PM +0000, Jarek Zgoda wrote:
David M. Wilson <dw***********@botanicus.net> pisze:
Unless you design some silly rules to determine when empty parenthesis
should be allowed - did a get assigned the return value of sys.exit()?
(yes I know it doesn't have one)
It has. The returned value is None.


A function must return to have a return value. When does sys.exit()
return?

Jp

--
Jarek Zgoda
Unregistered Linux User # -1
http://www.zgoda.biz/ JID:zg***@chrome.pl http://zgoda.jogger.pl/
--
http://mail.python.org/mailman/listinfo/python-list


Jul 18 '05 #43

P: n/a
On Sat, 20 Dec 2003 06:38:20 -0500, "John Roth" <ne********@jhrothjr.com> wrote:

"Bengt Richter" <bo**@oz.net> wrote in message
news:bs**********@216.39.172.122...
On Fri, 19 Dec 2003 20:22:38 -0500, "John Roth" <ne********@jhrothjr.com>wrote:
>
>"Steve Lamb" <gr**@despair.dmiyu.org> wrote in message
>news:sl*****************@dmiyu.org...
>> On 2003-12-20, John Roth <ne********@jhrothjr.com> wrote:
>> > a third is the ability to forget the empty parenthesis after
>> > a function/method call that doesn't require parameters.
>>
>> class ThisIs:
>> avariable = 'a'
>> def amethod(self):
>> return 'b'
>>
>> thisis = ThisIs()
>> print thisis.avariable
>> print thisis.amethod()
>> import this
>> print "Read line 2."
>
>I'm not sure what your point is. Your example isn't going
>to produce the expected result if you say:
>
>print thisis.amethod
>
>instead of
>
>print thisis.amethod()
>
>That is the place where I find Ruby syntax to be
>helpful: the amount of time where I want the method /
>function object is *far* lower than the amount of
>time I want to call it. It's one of those conundrums
>that doesn't seem to have a clean answer, though.
>

Ok, for line 2, run this ;-)

class ThisIs:
avariable = 'a'
def amethod(self):
return 'b'
def silly(self):
return 'heh'
silly = property(silly)

thisis = ThisIs()
print thisis.avariable
print thisis.amethod()
print thisis.silly
import sys
class L2(list):
def write(self, s): self.append(s)
sys.stdout = L2()
import this
L2 = ''.join(sys.stdout).splitlines()[2]
sys.stdout = sys.__stdout__
print "Read line 2."
print '... which is:', L2

Regards,
Bengt Richter


I think you're missing the point I was trying to make.

Sorry, I was being superficial. BTW, the output of the above is
----
a
b
heh
Read line 2.
.... which is: Beautiful is better than ugly.
----
;-)
Sure, you can use a property to not have to put
in the explicit function call, but then you can't put
in the explicit function call *anywhere* you use that
property.
Nor can you supply explicit arguments if you want to, though you could
provide an alternate name, so you could access either way.
Nor can we do properties without accessing them via the attribute magic (i.e.,
not via bare global names for example).
Ruby syntax makes it *optional*. That's what is
missing here.

I've floated various ideas/brain_farts more/less seriously for triggering magic
via name access alterantive to getattr magic, but there seems to be no enthusiasm
or else horrification at the thought, so I haven't stirred that pot for some time ;-)

What would be the syntax you would like to use, with what effect?

Regards,
Bengt Richter
Jul 18 '05 #44

P: n/a
Quoth "John Roth" <ne********@jhrothjr.com>:
....
| The world changes, and ideas that seemed to be perfectly appropriate
| five or ten years ago may no longer be such. Small languages with a limited
| audience have a perfect right to be as quirky or as "pure" as their authors
| want. Once they get beyond that point, there's a bit of social responsibility
| involved in addressing common problems.

For some definition of "common problems", that might be somewhat
true, though perhaps stretching it a bit even at that. We are
after all talking about free as in beer.

The things we seem to be discussing in this thread do not at all
meet the definition I have in mind. The main point when evaluating
a "common problem" in this context is whether it's really a problem.

Donn
Jul 18 '05 #45

P: n/a

John> The world changes, and ideas that seemed to be perfectly
John> appropriate five or ten years ago may no longer be such. Small
John> languages with a limited audience have a perfect right to be as
John> quirky or as "pure" as their authors want. Once they get beyond
John> that point, there's a bit of social responsibility involved in
John> addressing common problems.

So fork Python and show how it could be done better. If that's the case,
people will either drift over to Python-JR, or (some of) your ideas will
find their way back into Python-GvR.

Or, as in the Emacs/XEmacs split, darts may be thrown across the void for
the forseeable future. ;-)

Skip

Jul 18 '05 #46

P: n/a
H.V
Skip Montanaro <sk**@pobox.com> wrote in message news:<ma*************************************@pyth on.org>...

Python's design doesn't admit the option of calling functions without the
parens. Perl's and Ruby's do. On the other hand, functions are first-class
objects in Python.
And that's a big plus for python. Forget this silliness about calling
functions without parentheses .

John> The jihad against the "functional" builtins is a good case in
John> point. The replacements for apply, map and filter seem to be
John> adequate, and in the case of list comprehensions, pretty darned
John> useful although I think that it's a rather baroque addition to an
John> otherwise very clear and comprehensible language.

I love LC's personally. They do replace map and filter completely and
do so in a very attractive manner. Which is not to say that i am
against map and filter but at least a 100% equivalent construct takes
their place (soon to be replaced by gen conprehensions, which is fine
by me as it's again a clean replacement)
Why do you call it a "jihad"? Guido has stated on multiple occasions that
he regretted adding functional constructs to the language. I still can't
get to the Python website (have to wait another two hours for my ISP to
reload its tables), but here's a Google pointer to an HTML-ized version of
his OSCON 2002 Powerpoint slides:

Given all that Guido has said about functional programming, i'm
starting to wonder why he even made functions first class in python .

http://216.239.41.104/search?q=cache...hl=en&ie=UTF-8

John> On the other hand, claiming that sum() is an adequate replacement
John> for reduce() is so silly that it borders on the absurd.

No, operationally that's a correct statement. People have looked at the use
of reduce() in a number of different contexts. In all but the rarest of
cases, reduce() was used to sum a list of numbers. sum() is a perfectly
adequate replacement in all but those rare cases and is easier to read as
well. As Guido mentioned in the talk I referenced above:

reduce()
nobody uses it, few understand it
a for loop is clearer & (usually) faster

I think no one even tries to understand the very concept of reducing
sequence to a single object using a rule . Sum is not a replacement of
this *concept*.
Just what is so wrong with having such a general tool available in a
programming language ? Doesn't it hurt to understand how to use it?

John> The only explanation I can come up with for that level of
John> absurdity is a desire to get rid of a feature, regardless of what
John> it looks like. In other words, a jihad (holy war.)
If you look at some recent python-dev threads, you'll see comments
similar to "..this should get rid of most of the uses of lambdas, we
only have a few cases left .." .
I just don't understand this burning need of some to make python
conceptually poorer by eliminating the very idea of an anonymous
function.
No, it's simply not used very much. Python never has been a very strong
functional language. It's always been a very strong object-oriented
language. Use it the way it's strongest.

I think Guido should put his money where his mouth is and simply
eliminate functions as first class objects then ! It'd be a clear and
definitive way of saying that he doesn't like functional programming.
Object oriented purists probably wouldn't care since they probably
never use functions in that way.
It'd also be a great relief for all those who find the idea of
functions being passed around "hopelessly hard, too complex, byzantine
because i prefer 36 nested for loops with breaks, continues because
they're sooo much easier to understand, etc " .
Then python can be exactly like java at last !

Think about it : As long as functions remain first class, some people
will program using a functional style (I surely intend to). The only
way to stop me from doing that is to remove functions from first class
status. If python ever gets very fast, people will reimplement things
like reduce in their own code or in a functional module.

John> There is no replacement for lambda in sight, even though lambda is
John> arguably the ***largest single*** one of the functional constructs
John> that needs work, and has obviously needed work for a long time.

Once again, you desire Python to be something it is not. If you want a
strong functional language, program in Lisp or Haskell.
Functions are supposedly first class, regular objects in python. Why
can't they be sometimes anonymous, just like tuples, lists and user
defined objects can ? One doesn't even need to consider other
languages to make this point.

John> The obvious replacement for lambda, which is some form of inline
John> block, has not been seriously discussed, with proposed syntax and
John> examples, anywhere I've seen it. Clearly, I'm not ominiscient, so
John> that doesn't mean it hasn't, though.

Anonymous blocks are not a replacement for lambdas, named functions are.
Are there objects in python that must always have a name in any
context whatsoever ? It seems to me that all objects even modules can
be anonymous in at least some context.
Why are people even wondering about adding code blocks when making
real anonymous functions work will do ?

I don't even get why some people who are against the anonymity of
lambdas seem quite ok with the anonymity of code blocks (given how
much more complex a code block can be compared to a lambda, how can
anonymity in their case be fine and not fine in the case of the much
simpler lambdas ?) .

Does anyone care about consistency in python ? For real, if you don't
want functional programming, make functions non first class and stop
claiming that they are objects just like every object.
Again, it's something that doesn't fit easily into Python's design. There
were several ternary operator proposals advanced, but none was a clear
winner. Guido's a conservative language designer for the most part. It's
better to leave it out than to put something in you'll regret later. PEP
308 wasn't the first time the ternary operator discussion has come up, by
the way. Functional programming, ternary operators, anonymous code blocks.
They've all been issues for a long time.


You seem to have a burr under your saddle about this stuff. I'm not sure
why. Maybe it's time to get out the curry comb...

Skip


svlf
Jul 18 '05 #47

P: n/a

John> On the other hand, claiming that sum() is an adequate replacement
John> for reduce() is so silly that it borders on the absurd.
No, operationally that's a correct statement. People have looked at
the use of reduce() in a number of different contexts. In all but
the rarest of cases, reduce() was used to sum a list of numbers.
sum() is a perfectly adequate replacement in all but those rare cases
and is easier to read as well. As Guido mentioned in the talk I
referenced above:

reduce()
nobody uses it, few understand it
a for loop is clearer & (usually) faster
HV> I think no one even tries to understand the very concept of reducing
HV> sequence to a single object using a rule . Sum is not a replacement
HV> of this *concept*. Just what is so wrong with having such a general
HV> tool available in a programming language ? Doesn't it hurt to
HV> understand how to use it?

It doesn't hurt to understand the concept of reduce(), but if it's never (or
very rarely) used, it's just extra (nearly dead) code which has to be
maintained. It's easy enough to write reduce() in Python, and if/when PyPy
is a reality shouldn't be any less efficient than the current C version.
No, it's simply not used very much. Python never has been a very
strong functional language. It's always been a very strong
object-oriented language. Use it the way it's strongest.
HV> I think Guido should put his money where his mouth is and simply
HV> eliminate functions as first class objects then !

There are lots of use cases for functions as first class objects which don't
intersect with the usual notions of functional programming. Here's one
rather silly example:

l = []
append = l.append
for i in range(25):
append(i)

Another less silly example is os.walk(). It's in some sense a specialized
map() function, so does overlap a bit more with the usual notion of
functional programming.

HV> If python ever gets very fast, people will reimplement things like
HV> reduce in their own code or in a functional module.

As well they should. It's a five-liner in Python. I've never used it for
anything but summing a list of numbers. That appears to be true of most
people.

John> There is no replacement for lambda in sight, even though lambda is
John> arguably the ***largest single*** one of the functional constructs
John> that needs work, and has obviously needed work for a long time.
Once again, you desire Python to be something it is not. If you want
a strong functional language, program in Lisp or Haskell.


HV> Functions are supposedly first class, regular objects in python. Why
HV> can't they be sometimes anonymous, just like tuples, lists and user
HV> defined objects can ? One doesn't even need to consider other
HV> languages to make this point.

Having functions as first-class objects doesn't mean you have to be able to
define anonymous functions. Functions as first-class objects worked just
fine before Guido introduced lambda to the language in Python 1.0.

HV> Does anyone care about consistency in python ? For real, if you
HV> don't want functional programming, make functions non first class
HV> and stop claiming that they are objects just like every object.

As I indicated above, "functions as first-class objects" is not synonymous
with "functional programming". There are plenty of uses for function
objects without considering map(), apply(), lambda(), filter(), reduce() and
friends.

Skip

Jul 18 '05 #48

P: n/a
su******@rocketmail.com (H.V) writes:
reduce()
nobody uses it, few understand it
a for loop is clearer & (usually) faster


I think no one even tries to understand the very concept of reducing
sequence to a single object using a rule . Sum is not a replacement of
this *concept*.
Just what is so wrong with having such a general tool available in a
programming language ? Doesn't it hurt to understand how to use it?


The new sum function actually seems like a kludge around a misdesign
of the operator module. operator.add(2,3,4) should return 9 instead
of throwing an error because operator.add can only take two args.
Then sum(some_list) can be replaced by operator.add(some_list). The
other functions in the operator module should be extended the same way.
Jul 18 '05 #49

P: n/a
H.V wrote in message <27**************************@posting.google.com>. ..
Skip Montanaro <sk**@pobox.com> wrote in message news:<ma*************************************@pyth on.org>...
Given all that Guido has said about functional programming, i'm
starting to wonder why he even made functions first class in python .
He didn't make them first-class. He made everything an object, which has
the consequence of making everything first-class.
I think no one even tries to understand the very concept of reducing
sequence to a single object using a rule . Sum is not a replacement of
this *concept*.
Just what is so wrong with having such a general tool available in a
programming language ? Doesn't it hurt to understand how to use it?
No, but it was deemed to not be useful or idiomatic enough to warrant a
builtin. The most common use-case (like, 99% most common) was simply
summing up numbers, so we got a clear and conscise (and faster) builtin for
that, and continue to do things idiomatically for the other use cases.

I tend to agree with this. I've never found a use for reduce, even trying
hard to think of where I might find a home for it in my code. All I've ever
done with it is sum things. Even the Numeric people don't seem to use
reduce, and it seems that they, of all people, would use it. It's simply,
for whatever reason, not Pythonic. People naturally gravitate to alternate
idioms to do things that reduce could do.

Whether sum itself should be a builtin instead of in math is another issue
altogether, but removing reduce from the builtins definately seems like a
good decision to me. It may not be the right decision in some other
language, but for whatever reason, Python doesn't use it much.
John> The only explanation I can come up with for that level of
John> absurdity is a desire to get rid of a feature, regardless of what John> it looks like. In other words, a jihad (holy war.)

If you look at some recent python-dev threads, you'll see comments
similar to "..this should get rid of most of the uses of lambdas, we
only have a few cases left .." .
I just don't understand this burning need of some to make python
conceptually poorer by eliminating the very idea of an anonymous
function.


Python isn't really big on being conceptually pure, just on being clean,
consistent, and easy-to-use and understand.

I think the drive to get rid of usecases for lambdas is rather the opposite
of what you seem to suspect: lambdas have so few uses as it is, that the
Pythonic bent towards using fewer keywords/builtins/constructs has inclined
people to see if those few use-cases are really unique enough to warrant the
special syntax, or if it can somehow be subsumed and eliminated by other,
more generally useful constructs.

I will argue in the following that lambda simply isn't very useful *to*
*Python.*
No, it's simply not used very much. Python never has been a very strong
functional language. It's always been a very strong object-oriented
language. Use it the way it's strongest.

I think Guido should put his money where his mouth is and simply
eliminate functions as first class objects then ! It'd be a clear and
definitive way of saying that he doesn't like functional programming.
Object oriented purists probably wouldn't care since they probably
never use functions in that way.
It'd also be a great relief for all those who find the idea of
functions being passed around "hopelessly hard, too complex, byzantine
because i prefer 36 nested for loops with breaks, continues because
they're sooo much easier to understand, etc " .
Then python can be exactly like java at last !


You've got it backwards: functions are first-class in Python *because*
everything in Python is an object. (Did you notice that functions have
attributes, like objects?) It would be impossible to make them *not* first
class! (Well, I guess not impossible, but it would require enormous kludgy
hacking at core Python internals, and will inevitably result in bugs that
would haunt Python for the rest of its days. Besides, it's inconsistent,
and Python hates special-cases.)

Anyway, the following is a fantastically common and powerful Python idiom
that requires functions (well, really methods) to be first-class:

class Dispatch(object):
def do_this(self): pass
def do_that(self): pass

def dispatch(self, cmd):
cmd = 'do_' + cmd
if hasattr(self, cmd):
getattr(self, cmd)()
else:
raise NotImplementedError

Just because functions are first-class in Python doesn't mean we have to use
them the way functional programmers use them. ;)
Think about it : As long as functions remain first class, some people
will program using a functional style (I surely intend to). The only
way to stop me from doing that is to remove functions from first class
status. If python ever gets very fast, people will reimplement things
like reduce in their own code or in a functional module.
Anyone is free to program in a functional manner. In fact, Guido was quite
amenable to the suggestion (I think by Hettinger) that there be a functional
module in the standard library, similar to how we have the itertools module
for generator fun.

However, we will remain free to point out how there's usually a more
straightforward Python idiom that does the same thing faster and more
clearly. ;) We all hope Python calls get fast enough that functional
programming in Python is not always slower, but, even if functional
constructs were faster than standard idiom, Python would still stick to
idiom, unless it needed to optimize.

Of the functional functions, the only one that can occasionally beat a
for-loop is map. Map is faster than anything else when the function used is
a builtin.

Remember that no matter how nice your lambda syntax gets, functional
programming will probably always be slow in Python, simply because calling
is slow in Python. Quite slow, in fact, and there's no obvious way around
that. So Python generally prefers solutions that do not involve calling
functions repeatedly, especially not functions as tiny as the ones you can
comfortably fit into a lambda. Given this, you can see why anonymous
functions don't make much sense for Python. Python would get rid of lambdas
before it tried to "make them better", and no one is sure what that would
entail. So just use 'def' and be happy.
John> There is no replacement for lambda in sight, even though lambda is John> arguably the ***largest single*** one of the functional constructs John> that needs work, and has obviously needed work for a long time.

Once again, you desire Python to be something it is not. If you want a
strong functional language, program in Lisp or Haskell.


Functions are supposedly first class, regular objects in python. Why
can't they be sometimes anonymous, just like tuples, lists and user
defined objects can ? One doesn't even need to consider other
languages to make this point.


They can be anonymous, but to be small enough to be anonymous means being
inefficient. Python simply does not go the way of small, throwaway
functions, because there's no obvious way to use them without morphing
Python into an entirely different "functional Python" language. And it will
still be slower than using for-loops.

John> The obvious replacement for lambda, which is some form of inline John> block, has not been seriously discussed, with proposed syntax and John> examples, anywhere I've seen it. Clearly, I'm not ominiscient, so John> that doesn't mean it hasn't, though.

Anonymous blocks are not a replacement for lambdas, named functions are.


Are there objects in python that must always have a name in any
context whatsoever ? It seems to me that all objects even modules can
be anonymous in at least some context.
Why are people even wondering about adding code blocks when making
real anonymous functions work will do ?


What does it mean to make them "work"? If you have an anonymous function,
where would you use it? map()? reduce()? But these are all slower and
less-intuitive to Pythonistas than using for-loops and list comprehensions.

So I would argue, there's no place to put anonymous functions to work in
Python. That's why they never do any. (Work, that is.)

If we make lambda some powerful construct that can have multi-line code,
we'd just scratch our heads and say, "why didn't you just use a def"? If
the function is long and involved enough, making it anonymous ceases to be
of any importance. We'd end up just assigning the lambda to a name anyway,
so what's the point?

In other words, why is:

def myname(): pass

somehow intrinsically worse than:

myname = lambda : pass

supposing the latter were legal? If lambda were in every way the same as
def, except that lambda is anonymous and def is not, and that lambda was
legal in more places, then certainly the lambda is more general than def,
and we should get rid of def, since Python does not like to have equivalent
constructs. But the only thing the latter has over the former is that the
latter can sometimes be used anonymously. "But," future Pythonistas will
say, "we hardly ever use these anonymously! Why don't we invent a new
syntax that allows us to define the name inline, like we see many other
languages happily doing." And then they reinvent def, and then the upstart
def-ites lobby Guido against the old-school lambda-ites, and lambda is
overthrown "because def," (speaking from the future, now), "replaces the
by-far-most common use case of lambda and does it more clearly, and the
little niche use of lambda that's left is so rare as to not be worth it
anyway. Guido Jr. the third, out."
I don't even get why some people who are against the anonymity of
lambdas seem quite ok with the anonymity of code blocks (given how
much more complex a code block can be compared to a lambda, how can
anonymity in their case be fine and not fine in the case of the much
simpler lambdas ?) .
It's not the anonymity. It just so happens that in Python, anonymity makes
no sense beyond very small functions placed into the call of these
functional functions for which we always have an equivalent for-loop or
list-comp construct that is faster and more Pythonic.

There simply aren't many places in Python where a function takes a function
as an argument. And those places where it does usually a for-loop is
clearer and faster (as I've been saying over and over). In other cases, the
function being passed is large enough that making it anonymous gains
nothing--you'd just have to use a name to refer to it anyway, in order to
make the code clear enough to read.

Or is:

map( lambda x:
<do some complex multi-line thing with x>
, range(10))

really clearer than just using def somewhere up above? It's not even clear
that anything like Python syntax could support such a construct, and in
anycase it is horribly unPythonic in its gnarish attempt to fit everything
into one construct. So, I could turn the tables and say "what's this
obsession with making things anonymous?" ;)

The only utility of an anonymous function is the ability to define a
function inline, within the calling construct, without polluting the
namespace. I.e., a "throwaway function". Now, how often in Python do all
those circumstance conjoin to make anonymous functions very useful? Not
very, especially because, as we said, function calling is slow in Python.
Does anyone care about consistency in python ? For real, if you don't
want functional programming, make functions non first class and stop
claiming that they are objects just like every object.


Umm...I don't understand. You can program functionally if you really want
to, but I don't see why Python should feel obligated to support your habit,
especially since it has its own way of doing things that is far more natural
(and, um, faster, at least now) to the Pythonic frame of mind. Pythonic is
a concept orthogonal to everything else, including "functional" and "OO".
Python doesn't define itself by saying "I am OO, not functional." Rather,
it examines itself, it peers into its own essence, and discovers, "hey,
there isn't much functional in here, but there's an awful lot of OO."
Python is something that simply *is*; definitions come later, and frankly
will always be inaccurate and provisional. "Pythonic" is like a culture;
undefinable and always evolving.

It's a tautology that a language best supports those who like the way that
language does things. So if you don't like the way Python does things, and
you prefer it did things in a more functional way, perhaps you would be
better supported by using a language that *did* do things in a more
functional way? It won't make you a bad (or even a lesser) person if you
don't use Python, but it might make you happier.

I mean really, fighting about languages is like fighting about the relative
moral worth of screwdrivers and hammers, and going from there to arguing
about whether it's better to use screws or nails.
--
Francis Avila

Jul 18 '05 #50

This discussion thread is closed

Replies have been disabled for this discussion.