
On 19 Jun 2008, at 5:53 pm, Jules Bean wrote:
Richard A. O'Keefe wrote:
- what you get is a reference to a variable (as you do in Scheme) but loop variables really are variables, not names for values, so lambdas created in different iterations of the same loop point so the same loop variable, and do not remember the value it had when they were created. The proposal explains how to work around this.
This one trips everyone up in Javascript.
What's going on here is a nasty interaction with the semantics of loops. In Smalltalk and Scheme (to name two languages with closures and mutable variables), each iteration of a loop in principle creates a new variable binding. Scheme example: (do ((i 0 (+ i 1)) (l '() (cons (lambda (x) (* x i)) l))) ((>= i 10) l)) is equivalent to let f i l = if i >= 10 then l else f (i + 1) ((\x -> x * i) : l) in f 0 [] except for i and l being potentially mutable in Scheme but not Haskell. The Smalltalk equivalent would be (0 to: 9) collect: [:i | [:x | x*i]] in which (a) each iteration creates a *new* i, and (b) method and block parameters are *not* mutable, because they never are in Smalltalk. Importing only values into closures would not work for Smalltalk. Consider the usual implementation of Smalltalk's equivalent of 'fold: Collection>> inject: initial into: function |r| r := initial. self do: [:each | r := function value: r value: each]. ^r The mutablity of r here really isn't a problem. Nor is the mutability of variables _as such_ really the problem in the PHP proposal. The problem is that it's the *same* variable every time. If PHP loops introduced new bindings on every iteration, this particular problem would not exist.