Pugs did not support inline variable declarations, largely because the problem caused by this construct:
{ say "values of β will give rise to dom!"; $x = $x + my $x if $x; #1 #2 #3 #4 } The evaluation order for the four $x is (#4, #2, #3, #1). However, because $Larry made it very clear that lexical scopes are lexical, (#1, #2) must refer to the same (outer) $x, and (#3, #4) refers to the inner $x. When implemented naively, this creates fragmented scopes in the PIL tree. To simplify code generation, I propose that we float all lexical declarations in a scope to the top of the scope, in the same place as its formal parameters. Of course, we will still reject bogus programs like this: # No previous $x available here { say $x; my $x; } But that means these now raises the same exception: sub f ($x) { my $x } sub f { my $x; my $x } Alternatively, this could raise a warning and treat the second my() as a no-op. Personally, I'm in favour of an exception. Under this scheme, the compiler will mark variable lookups to the outer scope explicit. The sample construct at the beginning of this post will get compiled to this form, leaving the evaluation order explicit: CODE( syms => [$x], body => [ SAY("values of β will give rise to dom!"), IF( cond => $x, body => ASSIGN( from => ADD( l => $OUTER::x, r => $x, ), into => $OUTER::x ) ); ] ); The only problem I see with it is that $CALLER::x from &ADD's position will refer to the inner, not the outer, $x. However, seeing that the two arguments are in different scopes, I think it is not worth keeping any promise about interaction between $CALLER:: and mid-block declarations anyway. Does this sound sane? Thanks, /Autrijus/
pgp5Nvjf0RpOJ.pgp
Description: PGP signature