On 8 Jul 2002 [EMAIL PROTECTED] wrote:
> caller with no args is the same as C<caller(1)> (for certain values of
> 'the same as'), caller(0) already returns the current execution
> context.

You're right.  I stand corrected.

> > If you can set a block's continuation at runtime, I think you should be
> > able to get it as well.  Then you can splice a function into a dynamically
> > defined control sequence like this:
> >
> > my $readfile is private = -> $x { process_data $x, ... };
> > sub add_post_handler (CODE $block2) {       # is public
> >     $block2.continuation($readfile.continuation);
> >     $readfile.continuation($block2.as_continuation);
> > }
> > sub read_file($data) { $readfile.($data) }
> > # ...
> > add_post_handler -> $x { uncompress $x };
> > my $sum = "blahblah";
> > add_post_handler -> $x { die unless $sum eq md5sum $x; $x };
> > read_file $foo;
> >
> > One good thing about this is that none of the blocks has to be aware of
> > continuations itself, and the continuation-handling ugliness can be
> > separated from the useful-work-doing ugliness.
>
> I think if you *always* want a function to return via a post handler
> then you should wrap that function:
>
>     old_sub := {
>         try {
>             if (wantarray) { () = $pre_handler->(@_) }
>             else { scalar $pre_handler->(@_) }
>             CATCH ShortCircuit { return .result }
>         }
>         my @res = wantarray ? &old_sub(*@_) : scalar &old_sub(*@_);
>         $post_handler.continuation(caller.as_continuation).(@_,@res);
>    }

What I want is "always until I next reconfigure my program," something
that may happen at runtime.  The wrapping approach will do this just fine
until you want to stick something in the middle.  You can always go with
an explicit array that gets iterated through by some sort of
meta-function, then splice things into the middle when necessary, but
continuations are another way to do this, and some people might prefer
them.  And they'd have the added benefit of handling want() contexts
automatically.  The old function, and not our caller, should (arguably)
provide the context for the new function's return, since the new function
isn't returning to its calling context.  Handling this doesn't seem
possible unless we have ways to get and set context along these lines:

my @fs;
sub meta_f {
        my @wants = ((map { $fs[$_].want } 1..$fs.last), want());
        for @fs; @wants -> $f; $w {
                state_my_desires($w);
                @_ = &$f(@_);
        }
}

And manual want-handling will be more error prone in Perl 6, since calling
contexts are richer.

> > I was thinking it would be useful to modify $block's continuation,
> > so every caller of $block would get the new continuation.  You could
> > always make a copy of $block (not sure of the syntax) if you wanted
> > to set up your own personalized version.
>
> That sets you up for very scary action at a distance. Essentially
> you're proposing C<come_from BLOCK>

But we can already do this in Perl 5:

my $func_next = sub { }
sub func {
        # do stuff
        goto &$next;
}

sub foo {
        $func_next = shift;
}

It is possible to create scary action at a distance, but not unavoidable.
We can describe this in terms of come_from, but I prefer to think of it as
BLOCK.go_to (It's to-MAY-to, I'm telling you!).

/s

Reply via email to