Paste number 66768: python does not support closures

Index of paste annotations: 4 | 3 | 2 | 1

Paste number 66768: python does not support closures
Pasted by: wingo
When:1 year, 11 months ago
Share:Tweet this! | http://paste.lisp.org/+1FIO
Channel:None
Paste contents:
Raw Source | XML | Display As
>>> def foo (x):
    def bar(y=None):
        if y is None: return x
        x = y
        return x
    return bar

>>> foo(3)
<function bar at 0xb7f7256c>
>>> _()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in bar
UnboundLocalError: local variable 'x' referenced before assignment

Annotations for this paste:

Annotation number 4: making the example work with Python 3.0
Pasted by: jamesh
When:1 year, 11 months ago
Share:Tweet this! | http://paste.lisp.org/+1FIO/4
Paste contents:
Raw Source | Display As
Andy's example will fail for both Python 2.x and 3.0 because 'x' in 'bar' is considered to be a local variable (which is the default unless you specify otherwise).

Python 2.x doesn't support rebinding a variable from a parent scope in its closures, so we can't make his example work without using some mutable variable type.

For Python 3.0 though, the new 'nonlocal' statement makes the function work as expected, updating the binding of 'x' in the parent scope.

>>> def foo (x):
...    def bar(y=None):
...        nonlocal x
...        if y is None: return x
...        x = y
...        return x
...    return bar

Annotation number 3: lambda style, with py2.5's new conditional expression
Pasted by: leif
When:1 year, 11 months ago
Share:Tweet this! | http://paste.lisp.org/+1FIO/3
Paste contents:
Raw Source | Display As
foo=lambda x: (lambda l=[x]: lambda y=None: 
    l[0] if y is None else l.__setitem__(0,y) or y)()

Annotation number 2: SML does not support closures??
Pasted by: qbwiz
When:1 year, 11 months ago
Share:Tweet this! | http://paste.lisp.org/+1FIO/2
Paste contents:
Raw Source | Display As
A straight translation of the python program to SML (which should support closures):
Standard ML of New Jersey v110.67 [built: Thu May  1 12:26:45 2008]
-
- fun foo x = let
=      fun bar y =
=        case y of SOME(y) => let val x = y in x end
=              | NONE => x
=   in
=     bar
=    end;
val foo = fn : 'a -> 'a option -> 'a
- foo(3)
= ;
val it = fn : int option -> int
- foo(3)(NONE);
val it = 3 : int
- foo(3)(SOME(5));
val it = 5 : int
- foo(3)(NONE);
val it = 3 : int
-

Just because you support closures, doesn't mean you support modifying variables in the outer scope.

               

Annotation number 1: How to support modifying the outer scope
Pasted by: xxx
When:1 year, 11 months ago
Share:Tweet this! | http://paste.lisp.org/+1FIO/1
Paste contents:
Raw Source | Display As
>>> def foo (x):
    l = [x]
    def bar(y=None):
        if y is None: return l[0]
        l[0] = y
        return l[0]
    return bar

>>> foo(3)
<function bar at 0xb7f7256c>
>>> _()
3

Colorize as:
Show Line Numbers
Index of paste annotations: 4 | 3 | 2 | 1

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.