5 ms·
As right as you can get them in an imperative programming language, perhaps, but the semantics of closing over environments containing mutable variables is stil
by ionfish 15y ago
As right as you can get them in an imperative programming language, perhaps, but the semantics of closing over environments containing mutable variables is still confusing to even the smartest of people (cf. [1]; it's about Python, but JavaScript has essentially the same nature in this regard).
[1] http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/ http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/
- sid0 15y agoNot ECMAScript Harmony! [1] And no, that isn't the definitive semantics of closing over mutable variables. It is one out of at least two possible semantics. [1] http://brendaneich.com/2010/11/paren-free/ http://brendaneich.com/2010/11/paren-free/ -- see the "Implicit Fresh Bindings" section.
- ionfish 15y agoHarmony's new for in construct implicitly introduces a fresh let binding per iteration, yes, but it doesn't fundamentally change the language semantics with regard to the kind of example Eich mentions. So while one can, in Harmony, write code that behaves in the way that people like Andrej Bauer expect, it doesn't mean that the language's closure semantics have suddenly changed. It's also hard for me to see how one could have a 'definitive' semantics without having at least one alternative—not that I claimed that either JS's closure semantics were the only ones going. Presumably the alternative you mean is where the variables present in the local environment are copied on creation of a closure. I'd also resist the idea that I claimed that JavaScript's closure semantics were in some way definitive, although I can see how one might infer that from what I did write. That being said, given the potential problems with the alternative, I would claim that they're a reasonable choice.
- sid0 15y agoit doesn't mean that the language's closure semantics have suddenly changed. Yes, but what are the issues with fresh let-bindings per iteration? Presumably the alternative you mean is where the variables present in the local environment are copied on creation of a closure. No, that's bad -- it leaves you unable to show that objects with mutable state are reducible to closures.
- SomeCallMeTim 15y agoLua's ability to bind a closure to a mutable variable is a very powerful ability that I use all the time. But due to the way loop variables are handled, the example that's "broken" in Python works "as expected" in Lua: fns = {} for i=1,10 do fns[i]= function() return i; end end for i=1,10 do print("fns[i]",fns[i]()) end This produces: fns[i] 1 fns[i] 2 fns[i] 3 fns[i] 4 fns[i] 5 fns[i] 6 fns[i] 7 fns[i] 8 fns[i] 9 fns[i] 10 If you change the set-up loop to look like this, though: local j for i=1,10 do j=i fns[i]= function() return i,j; end end ...then it prints: fns[i] 1 10 fns[i] 2 10 fns[i] 3 10 fns[i] 4 10 fns[i] 5 10 fns[i] 6 10 fns[i] 7 10 fns[i] 8 10 fns[i] 9 10 fns[i] 10 10 In that case, it has bound the mutable "j" to each of the 10 closures, though you can see it's created a new binding for i on each pass through the loop. It WILL create a new instance of the mutable "j" each time "local j" is executed, though, so if the above code is in a function or another block that's executed more than once, then each time those functions will be bound to a new "j". EDIT: Get the code markup right.