No Let-over-Lambda in Python 2 :(
Standard idiom in LISP (or in this case, Scheme), Let over Lambda (also the title of an impressive book on LISP macros by Doug Hoyte):
(define (mkcounter) (let ((n 0)) (lambda () (begin (set! n (+ 1 n)) n))))
What does it do? It returns a function that returns 1, 2, 3, ... when called repeatedly. It's a way of keeping state in a world of functions. Don't confuse it with C's
staticVariables inside functions.
mkcounterconstructs a new counter object for each invocation, sowould print
(define c1 (mkcounter)) (define c2 (mkcounter)) (c1) (c1) (c1) (c2) (print (c1)) (print (c2))
An attempt to reconstruct this in Python 2.x:
def mkcounter(): n = 0 def _inner_(): n = n+1 return n return _inner_ c1=mkcounter() print c1()
UnboundLocalError: local variable 'n' referenced before assignment, which is somewhat confusing, since
nis visible in
n = n+1line is removed.
The impossibility of LoL in Python has been pointed out in PEP-3104 but was only fixed in Python 3. In Python 3 it's possible to reconstruct LoL by the dubiously named
def mkcounter(): n = 0 def _inner_(): nonlocal n n = n + 1 return n return _inner_ c1=mkcounter() print(c1())