Re: Reflection...
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...
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...
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...
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...
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...
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