Re: RFC 88: Possible problem with shared lexical scope.
Peter Scott wrote: > > > > Tony Olekshy wrote: > > > > > > > try { fragile(); } > > > > catch { my $caught = 1; } > > > > finally { $caught and ... } > > > > > It should work as though each pair of } ... { in between try { and > the end of the last finally or catch block isn't there. Storage > for lexicals is allocated at compile time, assignment happens at > run time. > > However, my memory as to what the current perl behavior is was > faulty; continue blocks do *not* share the lexical scope of their > attached loop blocks. > > So no, what I'm proposing is not the same as anything currently in > Perl. But I think it's a good reason anyway (and why shouldn't > continue blocks share the same scope? Not so 'lexical', I > suppose. Oh well.) RFC 88v2d6 now leaves in shared lexical scope and says the following under ISSUES + Lexical Scope: If it is not possible to have try, catch, and finally blocks share lexical scope (due, perhaps, to the vagaries of stack unwinding), this feature can simply be deleted, and the outer scope can be shared. One possible problem is illustrated by this: try { fragile(); } catch { my $caught = 1; } finally { $caught and ... } If fragile() doesn't throw then finally is going to test $caught even though the my statement was never exccuted. These matters will have to be referred to the internals experts. Yours, &c, Tony Olekshy
Re: RFC 88: Possible problem with shared lexical scope.
At 06:48 PM 8/20/00 -0600, Tony Olekshy wrote: >Dave Rolsky wrote: > > > > Tony Olekshy wrote: > > > > > try { fragile(); } > > > catch { my $caught = 1; } > > > finally { $caught and ... } > > > > If all those pieces were in the same scope I think it would still > > work like this (in Perl5-ish code): > > > > { > > try { fragile(); # It must be Italian } > > my $caught; > > catch { $caught = 1; } > > finally { $caught and ... } > > } > > > > It's the same as in perl5 with a block: > > > > { > >print $foo; > >my $foo = 1; > > } > > > > This is a compile time error because $foo isn't in scope til its > > declared. > >But in the shared scope, $catch isn't referenced until after the my >in lexical order. I'm just worrying about the details of what happens >during the dynamics of execution. I think it's more like saying: > > { > if ($foo) { my $bar = 1; } > $bar and ... > } > >where the outer block represents this "shared lexical scope" concept. >For this to work, doesn't storage for $bar have to be allocated and >initialized to undef at the beginning of the outer block? Nope. It should work as though each pair of } ... { in between try { and the end of the last finally or catch block isn't there. Storage for lexicals is allocated at compile time, assignment happens at run time. You can coerce some odd-looking behavior out of perl if you exploit this. However, my memory as to what the current perl behavior is was faulty; continue blocks do *not* share the lexical scope of their attached loop blocks. I was misremembering the caveat at the end of this part of perlsyn (which says the opposite, and is easily confirmed): >Perl's C-style for loop works exactly like the corresponding while loop; that >means that this: > > for ($i = 1; $i < 10; $i++) { > ... > } > >is the same as this: > > $i = 1; > while ($i < 10) { > ... > } continue { > $i++; > } > >(There is one minor difference: The first form implies a lexical scope for >variables >declared with my in the initialization expression.) So no, what I'm proposing is not the same as anything currently in Perl. But I think it's a good reason anyway (and why shouldn't continue blocks share the same scope? Not so 'lexical', I suppose. Oh well.) -- Peter Scott Pacific Systems Design Technologies
Re: RFC 88: Possible problem with shared lexical scope.
Dave Rolsky wrote: > > Tony Olekshy wrote: > > > try { fragile(); } > > catch { my $caught = 1; } > > finally { $caught and ... } > > If all those pieces were in the same scope I think it would still > work like this (in Perl5-ish code): > > { > try { fragile(); # It must be Italian } > my $caught; > catch { $caught = 1; } > finally { $caught and ... } > } > > It's the same as in perl5 with a block: > > { >print $foo; >my $foo = 1; > } > > This is a compile time error because $foo isn't in scope til its > declared. But in the shared scope, $catch isn't referenced until after the my in lexical order. I'm just worrying about the details of what happens during the dynamics of execution. I think it's more like saying: { if ($foo) { my $bar = 1; } $bar and ... } where the outer block represents this "shared lexical scope" concept. For this to work, doesn't storage for $bar have to be allocated and initialized to undef at the beginning of the outer block? Yours, &c, Tony Olekshy
Re: RFC 88: Possible problem with shared lexical scope.
On Sun, 20 Aug 2000, Tony Olekshy wrote: > That would be nice. But does this mean that in the following > case: > > try { fragile(); } > catch { my $caught = 1; } > finally { $caught and ... } > > storage for $caught is allocated and initialized to undef at the > beginning of the *try* block, even though you're not allowed to > see it there? Finally has to see it, as undef, even if the catch > block isn't entered. If all those pieces were in the same scope I think it would still work like this (in Perl5-ish code): { try { fragile(); # It must be Italian } my $caught; catch { $caught = 1; } finally { $caught and ... } } It's the same as in perl5 with a block: { print $foo; my $foo = 1; } This is a compile time error because $foo isn't in scope til its declared. Of course, what I know about the Perl internals fits on the head of a pin so someone more knowledgeable should feel free to jump in. -dave /*== www.urth.org We await the New Sun ==*/
Re: RFC 88: Possible problem with shared lexical scope.
Dave Rolsky wrote: > > On Sun, 20 Aug 2000, Tony Olekshy wrote: > > > try { my $p = P->new; my $q = Q->new; ... } > > finally { $p and $p->Done; } > > finally { $q and $q->Done; } > > > > If P->new throws, then the second finally is going to test > > $q, but it's not "in scope" yet (its my hasn't been seen). > > Or is it? If it isn't, I'll take shared lexical scoping out > > and put a note about this in ISSUES instead of the current: > > This is not an issue (at least if my works in Perl 6 as it does in Perl > 5). The scoping is determined at compile time so $q will be in scope > after this chunk is parsed. At run time it may or may not get something > assigned to it but your code already checks that. That would be nice. But does this mean that in the following case: try { fragile(); } catch { my $caught = 1; } finally { $caught and ... } storage for $caught is allocated and initialized to undef at the beginning of the *try* block, even though you're not allowed to see it there? Finally has to see it, as undef, even if the catch block isn't entered. Yours, &c, Tony Olekshy
Re: RFC 88: Possible problem with shared lexical scope.
On Sun, 20 Aug 2000, Tony Olekshy wrote: > Shared: > > try { my $p = P->new; my $q = Q->new; ... } > finally { $p and $p->Done; } > finally { $q and $q->Done; } > > If P->new throws, then the second finally is going to test > $q, but it's not "in scope" yet (its my hasn't been seen). > Or is it? If it isn't, I'll take shared lexical scoping out > and put a note about this in ISSUES instead of the current: This is not an issue (at least if my works in Perl 6 as it does in Perl 5). The scoping is determined at compile time so $q will be in scope after this chunk is parsed. At run time it may or may not get something assigned to it but your code already checks that. -dave /*== www.urth.org We await the New Sun ==*/
RFC 88 v2 draft 5 is available via http.
This version will be published after Peter Scott gets a chance to review the last days' changes (he's co-author now), and I make any adjustments necessitated by your reviews, dear reader ;-) Formatted: http://www.avrasoft.com/perl/rfc/rfc88v2d5.htm POD as text: http://www.avrasoft.com/perl/rfc/rfc88v2d5.txt Three major changes have happened to RFC 88 since v1, based mostly on everyone's effort to get me to simplify things. 1. The "except" keyword is gone, "catch" takes optional arguments instead. In terms of all the examples I have been writing, the result is, I think, much more readable. 2. Multiple conditional catch clauses now work like a switch, instead of like a bunch of sequential ifs. This always bugged me too, but I couldn't nail it down until the debate about using else/switch instead of catch. 3. A built-in Exception-based Error class is no longer defined. That was a bad idea waiting to die in the light of the other, better, mechanisms now made available in the RFC (mainly, the way C works now). Thanks again to everyone. Yours, &c, Tony Olekshy
Re: RFC 88: Possible problem with shared lexical scope.
Tony Olekshy wrote: > Non-shared: > > my ($p, $q); > try { $p = P->new; $q = Q->new; ... } > finally { $p and $p->Done; } > finally { $q and $q->Done; } > > Shared: > > try { my $p = P->new; my $q = Q->new; ... } > finally { $p and $p->Done; } > finally { $q and $q->Done; } In RFC 119v2, you would simply say: my $p = P->new finally $p->Done; my $q = Q->new finally $q->Done; ... No problem with scoping, because the cleanup code is in the same scope as the setup code, and defined not to be executed at cleanup time unless the setup code has been executed. (Tony, still haven't reread D88v3, coming later. Tomorrow?) > If P->new throws, then the second finally is going to test > $q, but it's not "in scope" yet (its my hasn't been seen). > Or is it? If it isn't, I'll take shared lexical scoping out > and put a note about this in ISSUES instead of the current: > > If it is not possible to have try, catch, and finally blocks > share lexical scope (due, perhaps, to the vagaries of stack > unwinding), this feature can simply be deleted, and the outer > scope can be shared. > > Yours, &c, Tony Olekshy -- Glenn = There are two kinds of people, those who finish what they start, and so on... -- Robert Byrne ___ Why pay for something you could get for free? NetZero provides FREE Internet Access and Email http://www.netzero.net/download/index.html
RFC 88: Possible problem with shared lexical scope.
Non-shared: my ($p, $q); try { $p = P->new; $q = Q->new; ... } finally { $p and $p->Done; } finally { $q and $q->Done; } Shared: try { my $p = P->new; my $q = Q->new; ... } finally { $p and $p->Done; } finally { $q and $q->Done; } If P->new throws, then the second finally is going to test $q, but it's not "in scope" yet (its my hasn't been seen). Or is it? If it isn't, I'll take shared lexical scoping out and put a note about this in ISSUES instead of the current: If it is not possible to have try, catch, and finally blocks share lexical scope (due, perhaps, to the vagaries of stack unwinding), this feature can simply be deleted, and the outer scope can be shared. Yours, &c, Tony Olekshy
Re: RFC 88: What does catch "Foo" { } do?
Peter Scott wrote: > > Tony Olekshy wrote: > > > > Graham Barr wrote: > > > > > > I am of the opinion that only a class name should follow catch. > > > If someone wants to catch based on an expression they should use > > > > > > catch { > > > if () { > > > } > > > else { > > > # rethrow the error > > > } > > > } > > > > Then you will be glad to know that RFC 88, in the not quite ready > > version two release, allows you do to just that. > > "Allows" isn't the same as "should be the only way" though. > > Graham, did you base your opinion on usability, parseability, both, > neither? And now for a slightly less frisky answer. The nice thing about the catch => form is not necessarily that you can say things like try { ... } catch $@->{severity} =~ /.../ => { ... } try { ... } catch grep { $_->isa("Foo") } @@ => { ... } try { ... } catch ref $@ =~ /.../ => { ... } but that within the scope of an application's code you can make available utility functions to allow really nice phrasing of rule-based catches (without having to re-raise), such as catch not &TooSevere => { ... } catch &AnyException("Error::IO") => { ... } my $test = sub { lines of predicate based on $@ }; catch &$test("Foo") => { ... } catch &$test("Bar") => { ... } ad infinitum Is there actually a good reason not to allow this functionality? Yours, &c, Tony Olekshy
Re: RFC 88: What does catch "Foo" { } do?
At 10:14 AM 8/20/00 -0600, Tony Olekshy wrote: >Graham Barr wrote: > > > > I am of the opinion that only a class name should follow catch. > > If someone wants to catch based on an expression they should use > > > > catch { > > if () { > > } > > else { > > # rethrow the error > > } > > } > >Then you will be glad to know that RFC 88, in the not quite ready >version two release, allows you do to just that. "Allows" isn't the same as "should be the only way" though. Graham, did you base your opinion on usability, parseability, both, neither? -- Peter Scott Pacific Systems Design Technologies
Re: RFC 88: What does catch "Foo" { } do?
Graham Barr wrote: > > I am of the opinion that only a class name should follow catch. > If someone wants to catch based on an expression they should use > > catch { > if () { > } > else { > # rethrow the error > } > } Then you will be glad to know that RFC 88, in the not quite ready version two release, allows you do to just that. Yours, &c, Tony Olekshy
Re: RFC 88: What does catch "Foo" { } do?
On Fri, Aug 18, 2000 at 11:04:03PM -0600, Tony Olekshy wrote: > As currently promulgated, catch "Foo" {} will always catch, > because "Foo" is true. Will this cause confusion for developers > who meant to say catch Foo {}? And what happens when someone > says catch "Foo", "Bar" {}? > > We can't just say that catch Foo {} and catch "Foo" {} are the > same thing, or that catch "Foo" {} is outlawed, because catch > $test {} is supposed to work even if $test *is* a string. > > Or can we? I'm not a parser expert. > > And while I'm on the topic, how likely is it that > > catch { ... } I am of the opinion that only a class name should follow catch. If someon wants to catch based on an expression they should use catch { if () { } else { # rethrow the error } } Graham.