I was thinking about regular expressions and hypotheticals again this weekend, and something was bothering me quite a lot. How do rules create hypotheticals?
Since a rule behaves like a closure, I can see how it could gain access to existing lexicals, if it's declared inside of the same scope: my $x = 1; / $x /; Good so far, now we change said lexical: my $x = 1; / $x := (2) /; Ok, got that. Now what about lexicals that aren't declared: / $x := (2) /; This bothers me. Yes, I can see how you could do it via %MY:: or however that's spelled (I'm typing this in a Vermont B&B, so I can't quite go check A2), but opening up the stack of my caller and mucking around with their contents seems rather rude. As Pink Floyd once said, "get your hands off of my stack!" So, here's an immodest proposal for kinder and gentler stack mucking. Essentially, these lexicals are out-of-band return values, and Perl 6 already has a mechanism for out-of-band return information: properties. When you look at it like this, what you want to do is "throw" these lexicals up the stack to your caller and let them do the right thing with them. Here's a non-regexp version of what I'm describing: sub a { my $x = 1; b(); print "x=$x y=$y\n"; } sub b { my $x = 2; my $y = 3; return undef but lexicals(x=>$x, y=>$y); } This has an unfortunate consequence: The existing lexical C<$x> gets stomped with the new value of 2. While this might be what you wanted in some cases, it's probably not a very good idea to allow it in general. So, lets say that that would generate a warning (error?), and in order to allow it, you would have to associate a property with your existing lexical: my $x is volatile = 1; I stole this property name from C, where it means that the variable's value might be stomped by some external side-effect, which is exactly what it means here. Every subroutine invocation would have to check return values for a lexicals property and instantiate any variables as needed. Variables created this way would be considered volatile so that: b(); b(); Would not generate warnings or errors about stomping the first call's variables with the second's. Going back to patterns, this gives us an added bonus. It not only explains the behavior of hypotheticals, but also of subexpression placeholders, which are created when the pattern returns: $self but lexicals(0=>$self, 1=> $self.{1}, 2=> $self.{2}, etc...) That yields the side effect that you can say: sub match_digits($string //= $_) { return / (\d+) /; } if match_digits("The time is 12:03") { print $1; } I think this is a very clean and simple way to get everything that patterns were supposed to do plus a lot of added benefit for things like: sub getpwuid(int $uid //= $_) { %pwd = external("getpwuid",$uid); return %pwd but lexicals(%pwd); } getpwuid($<); print "I am $user from $dir, and I have a secret ($passwd)\n"; You should be able to "protect" yourself from these side effects. There are two ways to do that: {getpwuid($<)} or getpwuid($<) but lexicals(); I would expect either one of those to work, though the second is a bit of magic in terms of order of events. -- Aaron Sherman <[EMAIL PROTECTED]> http://www.ajs.com/~ajs