The Shœstring Foundation Weblog About The Shœstring Foundation Weblog, Miscellaneous Byproducts Matthias Bauer `bauerm (at) shoestringfoundation · org ` reop pubkey Vignettes by George Herriman Subscribe to a syndicated feed of my weblog, brought to you by the wonders of RSS. Mon, 15 Jul 2013 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 `static` Variables inside functions. `mkcounter` constructs a new counter object for each invocation, so ```(define c1 (mkcounter)) (define c2 (mkcounter)) (c1) (c1) (c1) (c2) (print (c1)) (print (c2)) ``` would print `4` `2`. 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() ``` fails with `UnboundLocalError: local variable 'n' referenced before assignment`, which is somewhat confusing, since `n` is visible in `_inner_` if the `n = n+1` line 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 `nonlocal` directive: ```def mkcounter(): n = 0 def _inner_(): nonlocal n n = n + 1 return n return _inner_ c1=mkcounter() print(c1()) ```