[Haskell-cafe] Lambda and closures in PHP -- could someone please
comment?
Richard A. O'Keefe
ok at cs.otago.ac.nz
Thu Jun 19 02:05:56 EDT 2008
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.
More information about the Haskell-Cafe
mailing list