lexical closures and python
aleax at aleax.it
Thu Sep 6 09:31:02 CEST 2001
"John Beppu" <beppu at binq.org> wrote in message
news:mailman.999755048.7248.python-list at python.org...
> My understanding is that Python does not support lexical closures.
> I've also heard that it should not be expected to appear any time
> in the near future. Can anyone confirm or deny this?
Python 2.2, currently in alpha-2, has full support for closures
including lexically nested scopes; in Python 2.1, currently released
as 2.1.1, support is there, too, but needs to be explicitly enabled
by placing at the start of the module:
from __future__ import nested_scopes
What you *can't* do in Python (just as you can't in FP languages
such as Haskell or ML dialects) is have a function *re-bind*
names in scopes it's nested in. If you choose to say that this
means "no support for lexical closures", be sure to let the
functional programming guys know -- they'll surely be very
interested to hear that, having never suspected it before:-).
(Python is not as pure as Haskell &c in making data immutable
and names non-rebindable -- other names CAN be re-bound, and
Python supports many kinds of mutable data objects, which can
perfectly well be mutated even when their names cannot be
re-bound -- but that's another issue, and, it seems to me, not
connected to whether a language supports lexical closures).
> I'm asking about closures here, because I didn't want to misrepresent
> Python in my writing. If lexical closures are on the horizon, I'd
> like to know about it. If not, I guess I could mention that Python
> provides a lambda function, but it's not what a Schemer would expect
> it to be. I'm trying to be correct, here.
I think the limitations of Python's lambda (which is not a function,
but a syntax special-form) may be worth mentioning, although they have
nothing to do with lexical closures: a Python lambda is limited to
an *expression*, and Python distinguishes between expressions and
statements, so the limitation is meaningful. On the other hand, it's
again strictly an issue of having to bind a name: wherever you might
use a lambda special-form, you can instead choose to define a local
function and pass the function's name instead.
For example, you CANNOT, in Python, write:
z += y
because lambda can only wrap an expression and "global z" as well as
"z += y" are *statements* instead. You can, however, perfectly well
write, to the same effect as that intended in the above invalid code:
z += y
More information about the Python-list