Re: Reflection...

2002-07-08 Thread Dan Sugalski

At 9:48 AM +0100 7/8/02, [EMAIL PROTECTED] wrote:
>That sets you up for very scary action at a distance. Essentially
>you're proposing C

Well, sure. How else are we going to handle the INTERCAL front-end? ;-P
-- 
 Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
   teddy bears get drunk



Re: Reflection...

2002-07-08 Thread Sean O'Rourke

On 8 Jul 2002 [EMAIL PROTECTED] wrote:
> caller with no args is the same as C (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

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




Re: Reflection...

2002-07-05 Thread Sean O'Rourke

On 5 Jul 2002 [EMAIL PROTECTED] wrote:

> dan <[EMAIL PROTECTED]> writes:
>
> > At 8:29 AM -0700 7/4/02, Sean O'Rourke wrote:
> > >Sick.  Anyways, I think it seems like a more natural way to do things than
> > >traditional call/cc.  "$block.continuation" reads as "where do I go after
> > >$block?"; "$block.continuation($foo)" as "after executing $block, proceed
> > >on to $foo"; "(call/cc func)" as "call func with a single argument being
> > >the 'rest of the current computation'".  This last definition makes Scheme
> > >and Lisp people happy, but (at least for me) the first two are much easier
> > >to grasp, as they refer to what's going on more concretely.
> >
> > If you want really sick, consider that we are *not* limited to the
> > standard call/cc functionality. Continuations can reasonably be taken
> > at any statement boundary. (They don't work well if taken from within
> > an expression. Or, if they do, it hurts my brain enough that I'd
> > rather you didn't...) You also should be able to invoke them anywhere,
> > including within expressions.
> >
> >
> > You're not obligated to pass the continuation for the call/cc into
> > call/cc (you could pass another one in if you chose), nor, I suppose,
> > are you obligated to not keep it around for later use.
>
> Okay, how about the following as a suggested syntax for getting
> at/using continuations.
>
> 1. You can get the current continuation by doing
>
>caller.continuation;

Does "caller" with no args mean "current execution context", with
caller(1) referring to our caller?  We also want to be able to take a
continuation right ahead of the current execution point within our current
function (kind of like a delayed fork), not just at the point where we
return to our caller.  I had originally written "caller(-1).continuation"
for this in a previous mail, but deleted it because it seemed only a
matter of time before some asked what caller(-2)  would do ;).

> 2. I don't think being able to do C<$block.continuation> is useful
>because continuations are runtime things.

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.

> 3. C<$block.continuation($a_continuation)> can be thought of as a kind
>of curry. It sets up a 'version' of a block which will return to
>C<$a_continuation>. This would mean you can then do:
>
>$block.continuation($a_continuation).(*@arglist);
>
>which calls C<$block> with @arglist, but the block then returns to
>the continuation.

By "a version, do you mean that $block.continuation($x) returns a copy of
$block with its new continuation?  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.

> [Unsatisfactory attempt to explain what a continuation is deleted
>  because *my* head started to hurt as I tried to explain it...]

I thought your examples (elided) did a fine job...

/s





Re: Reflection...

2002-07-04 Thread dan

At 8:29 AM -0700 7/4/02, Sean O'Rourke wrote:
>Sick.  Anyways, I think it seems like a more natural way to do things than
>traditional call/cc.  "$block.continuation" reads as "where do I go after
>$block?"; "$block.continuation($foo)" as "after executing $block, proceed
>on to $foo"; "(call/cc func)" as "call func with a single argument being
>the 'rest of the current computation'".  This last definition makes Scheme
>and Lisp people happy, but (at least for me) the first two are much easier
>to grasp, as they refer to what's going on more concretely.

If you want really sick, consider that we are *not* limited to the 
standard call/cc functionality. Continuations can reasonably be taken 
at any statement boundary. (They don't work well if taken from within 
an expression. Or, if they do, it hurts my brain enough that I'd 
rather you didn't...) You also should be able to invoke them 
anywhere, including within expressions.

You're not obligated to pass the continuation for the call/cc into 
call/cc (you could pass another one in if you chose), nor, I suppose, 
are you obligated to not keep it around for later use.
-- 
 Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
   teddy bears get drunk



Re: Reflection...

2002-07-04 Thread Sean O'Rourke

On 4 Jul 2002 [EMAIL PROTECTED] wrote:

> Dan Sugalski <[EMAIL PROTECTED]> writes:
>
> > At 8:32 AM +0100 7/3/02, [EMAIL PROTECTED] wrote:
> > >
> > >For true scariness, consider:
> > >
> > > $sub.current_continuation($new_continuation);
> > >
> > Some days you really, really scare me Piers...
>
> Heh. Scary can be good.
>
> > This would be an interesting thing to do, though. I don't see why it
> > couldn't be done.
>
> You know, the more I think about it, I'm not sure it *is* a good
> idea. Once you have continuations in play you could have multiple
> 'live' continuations associated with a single sub, so how would you
> decide *which* continuation was the important one.

All of them!  I don't see how the getter/setter mentioned above would
automatically lead down this path to madness, but it's madness I kind of
like.  If I'm not confused, the insane version lets you do threading:

$current_block.push_continuation($some_continuation)

or quantum shenanigans:

$current_block.push_continuation(any(*@some_ccs))

And the sane one allows dynamically-joined blocks:

$block1 = { ... }
$block2 = { ... }
$block1.continuation($block2.as_continuation);
$block1($something);# evaluate block1 then block2, then keep going

Sick.  Anyways, I think it seems like a more natural way to do things than
traditional call/cc.  "$block.continuation" reads as "where do I go after
$block?"; "$block.continuation($foo)" as "after executing $block, proceed
on to $foo"; "(call/cc func)" as "call func with a single argument being
the 'rest of the current computation'".  This last definition makes Scheme
and Lisp people happy, but (at least for me) the first two are much easier
to grasp, as they refer to what's going on more concretely.

/s




Re: Reflection...

2002-07-03 Thread Dan Sugalski

At 8:32 AM +0100 7/3/02, [EMAIL PROTECTED] wrote:
>[EMAIL PROTECTED] writes:
>
>>  Just a thought, I hope that we're going to be able to do things like:
>>
>>  my $sub = {$^a + $^b};
>>
>>  $sub.arity; # 2
>>  $sub.prototype; # ('$^a', '$^b')
>>
>>  Getting access to this sort of thing will make the life of someone,
>>  say, writing a refactoring browser, so much easier...
>
>And, for scary madness, how about:
>
> $sub.current_continuation;
>
>For true scariness, consider:
>
> $sub.current_continuation($new_continuation);
>
>Which may well make a certain amount of sense from an AOP point of
>view.
>
> ...
> $target.current_continuation($post_handler_continuation);
> ...

Some days you really, really scare me Piers...

This would be an interesting thing to do, though. I don't see why it 
couldn't be done.
-- 
 Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
   teddy bears get drunk