Lisp-likeness

Michele Simionato michele.simionato at gmail.com
Wed Mar 16 07:07:31 EST 2005


Carl Banks:
> Python might lose when it comes to functional programming,
> but it wins when it comes to nested functions like this (where
a,b,c,d
> are in the enclosing scope and presumably changing):

>   def print_variables():
>        print a,b,c,d

Yes, clearly if I have

def toplevel():
    a = 1
    def f():
        print a
    a = 2
    f()

toplevel()

I want 2 to be printed, not 1.

> If Python did it the way Scheme did, this would be pretty useless.

But notice that Scheme has no problems whatsoever:

(define (toplevel)
  (define a 1)
  (define (f)
    (display a))
  (set! a 2)
  (f))

(toplevel)

prints 2 the same as in Python.

> IMO, this sort of usage is FAR more common than the functional usage
as
> a closure inside a loop.

Maybe, but for me it is quite common to have closures inside loops
(typically for callbacks in Tkinter or a Web framework).

> Closing on a value rather than a variable would have been a lot
easier
> to implement.  I'm sure there was talk about which way to do it in
the
> discussions about adding nested scopes to the language, and if the
> Python gods felt closing on a variable wasn't significantly more
useful
> than closing on a value, I doubt they would have done that.

I have no doubt about that. Still, there are people who disagrees
with Guido's choice, even on python-dev. This was a tough decision
to make, with pros and contras. It would be possible to change
the current default and have a more Schemish/Haskellish syntax
for loops: it would be enough to internally convert something like

result = []
for i in range(10):
    result.append(lambda : i)

into

result = []
def for_block(i):
    result.append(lambda : i)
for i in range(10): for_block(i)

However this approach has a drawback (which is not there in Scheme,
since Scheme has set!): if a new scope was created at each iteration
(which is what the function call is doing) we could not reassign
variables (i.e. they would become names locals to the "for" scope,
touching them would not affect variables outside the scope).
So this idiom

a = ""
for i in range(10):
  if i == 5: a = "5 was reached"
print a

would not work. So, as I said, there are pros and contros.
Personally, I like better the Scheme way (what I do not like
in Scheme is the issue of inner defines vs. toplevel defines,
but this is another story).

               Michele Simionato




More information about the Python-list mailing list