On Wed, Feb 1, 2017 at 3:06 PM, Rowan Collins <rowan.coll...@gmail.com> wrote:
> On 01/02/2017 20:17, Rasmus Lerdorf wrote: > >> You probably think of $var as being a local scope variable here, >> but really it isn't. It is an imported variable that happened to not exist >> in the outer scope and it was assigned a value in the inner scope, but >> that >> assignment can't leak back out so it is still unassigned in the outer >> scope. >> > > I'm very confused by your terminology here. You definitely talk about two > distinct scopes, "the inner scope" and "the outer scope", but then you > assert that there is no "local scope". Surely the "inner scope" is "local" > to the closure? > > In actual fact, it's local to *each invocation* of the closure, because > the function is initialised with the original values each time. For > instance: > > $a = 1; > $fn = fn() => ++$a; > $a = 42; > echo $fn(), ' ', $fn, ' ', $fn(); > > This echoes 2 2 2, not 2 3 4, because the $a being incremented is new for > each invocation. Nor does it echo 43 43 43, because it is only the value of > $a that is captured, not its reference. > > I think the best description is this: the closure has its own scope, which > is initialised on each invocation with a copy of another scope taken when > it was defined. > > > To go back to Bruce's question, the original statement was: > > you don't typically need a local scope at all for these short closures >> > > The important point here is that within a single expression there is very > little you can meaningfully do with a local scope other than read from it. > It's generally a bad idea to alter the value of a variable and expect > another part of the same expression to see the new value, because you can't > always predict how the compiler will rewrite the expression (I think an > example of this came up on the list a while back, but can't think how to > search for it). > > So for most purposes you can consider all the automatically imported > variables to be immutable values, which makes their scope much less > relevant. It is mostly a semantic thing. Of course you have a local scope, but because of automatic import you don't have a clean local scope so it is not like the function-local scope people are used to. Like you said, it is a mostly immutable copy of the outer scope. But people need to understand that the immutability doesn't apply to class variables because there is no automatic clone done on outer scope objects. class C { static $var = 1; } $f = fn() => C::$var++; echo $f().$f().$f(); will output 123 and the value of C::$var would be 4 after this. -Rasmus