Python syntax in Lisp and Scheme

Jason Creighton androflux at softhome.net.remove.to.reply
Sat Oct 4 18:34:22 EDT 2003


On Sat, 04 Oct 2003 17:02:41 GMT
Alex Martelli <aleax at aleax.it> wrote:

> > As Paul Graham says (<URL:http://www.paulgraham.com/icad.html>):
> >>  or even
> >> 
> >> def foo(n):
> >>   lambda i: n += i
> 
> And this touches on yet another point of the Zen of Python:
> explicit is better than implicit.  Having a function
> implicitly return the last expression it computes would
> violate this point (and is in fact somewhat error-prone,
> in my experience, in the several languages that adopt
> this rule).

I don't mean to start a flamewar....ah, who am I kidding, of *course* I
mean to start a flamewar. :-)

I just wish the Zen of Python (try "import this" on a Python interpreter
for those who haven't read it.) would make it clearer that "Explicit is
better than implicit" really means "Explicit is better than implicit _in
some cases_"

Look here:

>>> [x*x for x in [1,2,3]]
[1, 4, 9]

Good grief! How could someone who doesn't understand list comprehensions
*ever* read and understand this? We'd better do it the explicit way:'

>>> ary = []
>>> for x in [1,2,3]:
...     ary.append(x*x)
... 
>>> ary
[1, 4, 9]
>>>

*Much* better! Now you don't have to understand list comprehensions to
read this code!

</sarcasm>

Of course, nobody is going to seriously suggest that list
comprehensions be removed from Python. (I hope). The point here is that,
for any level of abstraction, you have to understand how it works. (I
think) what the author of "The Zen of Python" (Tim Peters) means when
he says "Explicit is better than implicit" is "Don't do weird crazy
things behind the programmer's back, like automatically have varibles
initialized to different datatypes depending on how they are used, like
some programming language we could mention."

I agree with most of the rest of "The Zen of Python", except for the
"There should be one-- and preferably only one --obvious way to do it."
bit. I think it should be "There should be one, and preferably only one
, *easy* (And it should be obvious, if we can manage it) way to do it."

For instance, let us take the ternary operator. Ruby has at least two
constructs that will act like the ternary operator.

if a then b else c end

and

a ? b : c

The "if a then b else c end" bit works because of Ruby's "return value is
last expression" policy.

In a recent thread in comp.lang.ruby, you (Alex Martelli) said:

But for the life of me I just can't see why, when one has
"if a then b else c end" working perfectly as both an expression
and a control statement, one would WANT to weigh down the language
with an alternative but equivalent syntax "a?b:c".

<end quote>

The reason I would want to weigh down the language with an alternative
syntax is because sometimes a ? b : c is the *easy* way to do it.
Sometimes you don't want do say:

obj.method(arg1, (if boolean then goober else lala end))

Sometimes you just want to be able to say:

obj.method(arg1, arg2, boolean ? goober : lala)

But the Python folks seems to like having only one way to write
something, which I argee with, so long as we have at least one easy way
to write something.

So there is a balance to be struck here. Some people like the way Python
does things; some people do not. This is why we all hate each other. :-)

No, really, that's why we have different languages.

> In Ruby, the spaces of methods and data are separate (i.e.,
> most everything is "an object" -- but, differently from
> Python, methods are not objects in Ruby), and I do not
> think, therefore, that you can write a method that builds
> and returns another method, and bind the latter to a name --
> but you can return an object with a .call method, a la:
> 
> def outer(a) proc do |b| a+=b end end

I would probably define this as;

def outer(a)
  proc { |b| a+=b }
end

I prefer the { } block syntax for one-line blocks like that. And I don't
like stick a whole function definition on one line like that. Makes it
harder to read, IMHO.

> x = outer(23)
> puts x.call(100)   # emits 123
> puts x.call(100)   # emits 223
> 
> [i.e., I can't think of any way you could just use x(100)
> at the end of such a snippet in Ruby -- perhaps somebody
> more expert of Ruby than I am can confirm or correct...?]

I will go on a little ego trip here and assume I'm more of a Ruby expert
than you are. :-)

Yes, you are pretty much correct. There are some clever hacks you could
do, but for the most part, functional objects in Ruby come without
sugar.

Jason Creighton




More information about the Python-list mailing list