[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