On 30 November 2010 18:37, Reini Urban <rurban@x-ray.at> wrote: > Zefram schrieb: >> >> Dave Mitchell wrote: >>> >>> What do you think is the bug? It seems to be behaving the way I expect. >> >> The code looks like it closes over the lexical variable $x. That lexical >> variable is then set to 6, so when the closure is later called (through >> the&foo name) it would be expected for it to return 6. This is how >> closures normally work, both in other languages, and in Perl when that >> particular form with the () prototype is not used. For the closure >> operation to return a constant-5 sub cannot be justified by reference >> to closure theory; it can only be explained as a special exception in >> Perl semantics, which is what it is. > > Sorry, I don't understand that special theory of yours. > Why on earth should > BEGIN{my $x = 5; *foo = sub(){$x}; $x=6} print foo' > ever print 6 again? Because if you take off the constant prototype () it does: $ perl -le'BEGIN{my $x = 5; *foo = sub(){$x}; $x=6} print foo' 5 $ perl -le'BEGIN{my $x = 5; *foo = sub {$x}; $x=6} print foo' 6 > We are using lexical scope, not dynamic scope. > With dynamic scoping, i.e. local $x = 5; you could justify a 6. > > Is it really that perl coders still cannot understand the difference between > lexical and dynamic scope? Given the above, that is a *bit* strong dont you think Reini? >> The generation of optimised constant subs is a useful facility. >> It certainly ought to be available, without having to invoke the >> installation-in-a-package behaviour of "use constant". But this exception >> to the closure rules is a poor way to make it available, since it breaks >> an otherwise logically consistent language feature. In my opinion, >> constant-sub creation should be made available via an XS function in some >> CPAN module (very easily arranged), and the magic behaviour of sub(){$x} >> should be phased out (less easy, probably requiring a deprecation cycle). > > Nothing to deprecate, sorry. > Optimizing the closure to a constant sub here is also fine. Only because we defined it so. Yves -- perl -Mre=debug -e "/just|another|perl|hacker/"Thread Previous | Thread Next