From: John Porter [mailto:[EMAIL PROTECTED]]
> Eric Roode wrote:
> > 
> >     sub func1
> >     {
> >         func2();
> >     }
> >     
> >     sub func2
> >     {
> >         last func1;
> >     }
> >     
> > ?  Imho, it is a BAD THING for functions to know who called them,
> > and to vary their behavior accordingly. 

I'm after a next/last/redo mechanism for the subroutine to short-circuit
itself.  Besides, you could apply the "bad coding" example to the current
implementation of short-circuiting loops. 

OUTER: while (1) {
  INNER: while (1) {
    func1();
  }
}

sub func1 {
  last OUTER;
}

My proposal would only allow such "bad coding" when someone does so with an
explicit label, otherwise the status quo is preserved. Let people who
explicitly chose to write bad code to do so. That's their choice. The
default behaviour would remain, and I'll able to short-circuit C<grep> and
C<map>.


> Yes.  This is a serious downside to the proposal, even though it was
> intended to allow last'ing out of some other kind of nested 
> scope, e.g.
> 
>       sub func1
>       {
>               while(1)
>               {
>                       last func1;
>               }
>       }
> 
> But if we keep the block types distinct, as I now believe we should,
> one would simply use C<return> there...

This wouldn't help C<grep>. you'd be returning from the context of the code
block... and not C<grep>. I want to short-circuit the built-in, and my own
subroutines that take code blocks.

sub mygrep (&@) {
  my ($coderef, @list, @results) = @_;
  &$coderef and push(@results, $_)  foreach (@list);
  @results;
}

mygrep {$_ == 1 and return $_} (1..1_000_000);

vs.

mygrep {$_ == 1 and return $_ && last mygrep} (1..1_000_000);


Garrett

Reply via email to