Re: RFC 88: Possible problem with shared lexical scope.

2000-08-20 Thread Tony Olekshy

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.

2000-08-20 Thread Peter Scott

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.

2000-08-20 Thread Tony Olekshy

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.

2000-08-20 Thread Dave Rolsky

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.

2000-08-20 Thread Tony Olekshy

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.

2000-08-20 Thread Dave Rolsky

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.

2000-08-20 Thread Tony Olekshy

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.

2000-08-20 Thread Glenn Linderman

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.

2000-08-20 Thread Tony Olekshy

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?

2000-08-20 Thread Tony Olekshy

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?

2000-08-20 Thread Peter Scott

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?

2000-08-20 Thread Tony Olekshy

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?

2000-08-20 Thread Graham Barr

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.