![](https://secure.gravatar.com/avatar/1e126970cb50fcf90ed4cb1a089ebd73.jpg?s=120&d=mm&r=g)
Nick Coghlan <ncoghlan@...> writes:
On 23 January 2016 at 14:50, Andrew Barnert via Python-ideas <python-ideas@...> wrote:
What the thread is ultimately looking for is a solution to the "closures capturing loop variables" problem. This problem has been in the official programming FAQ[1] for decades, as "Why do lambdas defined in a loop with different values all return the same result"?
powers = [lambda x: x**i for i in range(10)]
This gives you ten functions that all return x**9, which is probably not what you wanted.
The reason this is a problem is that Python uses "late binding", which in this context means that each of those functions is a closure that captures the variable i in a way that looks up the value of i at call time. All ten functions capture the same variable, and when you later call them, that variable's value is 9.
I've never liked the use of "late binding" in this context. The behavior is totally standard for closures that use mutable values. Here's OCaml, using refs (mutable reference cells) instead of the regular immutable values. BTW, no one would write OCaml like in the following example, it's just for clarity): let i = ref 0.0;; # val i : float ref = {contents = 0.} let rpow = ref [];; # val rpow : '_a list ref = {contents = []} while (!i < 10.0) do rpow := (fun x -> x**(!i)) :: !rpow; i := !i +. 1.0 done;; - : unit = () let powers = List.rev !rpow;; val powers : (float -> float) list = [<fun>; <fun>; <fun>; <fun>; <fun>; <fun>; <fun>; <fun>; <fun>; <fun>] List.map (fun f -> f 10.0) powers;; - : float list = [10000000000.; 10000000000.; 10000000000.; 10000000000.; 10000000000.; 10000000000.; 10000000000.; 10000000000.; 10000000000.; 10000000000.] # You see that "i" is a reference cell, i.e. it's compiled to a C struct and lookups are just a pointer dereference. Conceptually Python's dictionaries are really just the same as reference cells, except they hold more than one value. So, to me the entire question is more one of immutable vs. mutable rather than late vs. early binding. Stefan Krah