On Fri, 2009-01-02 at 22:56 +0100, Aristotle Pagaltzis wrote:
When I asked this question on #perl6, pmurias suggested using
gather/take syntax, but that didn't feel right to me either --
it's contrived in a similar way to using a one-off closure.
Contrived how?
Meaning, the gather/take syntax doesn't make much sense, because we're
not "gathering" anything; the PID file handler has nothing to return.
We'd only be using it for the "side effect" of being able to pause the
callee's execution and resume it later.
When you have an explicit entity representing the continuation,
all of these questions resolve themselves in at once: all calls
to the original routine create a new continuation, and all calls
via the state object are resumptions. There is no ambiguity or
subtlety to think about.
I like this argument. I'm not sure it's applicable in every case, but
it certainly applies to the class of situations containing my problem.
So from the perspective of the caller, I consider the “one-off”
closure ideal: the first call yields an object that can be used
to resume the call.

However, I agree that having to use an extra block inside the
routine and return it explicity is suboptimal. It would be nice
if there was a `yield` keyword that not only threw a resumable
exception, but also closed over the exception object in a
function that, when called, resumes the original function.

That way, you get this combination:

sub pid_file_handler ( $filename ) {
# ... top half ...
# ... bottom half ...

sub init_server {
# ...
my $write_pid = pid_file_handler( $options<pid_file> );
# ...
That's pretty nice. Perhaps we can make it even cleaner with a few
small tweaks to init_server():

sub init_server(:$pid_file, ...) {
# ...
my &write_pid := pid_file_handler($pid_file);
# ...

So far, this variant is winning for me, I think. It's slightly more
verbose on the caller's side than the yield variant I had proposed, but
it's also more explicit, and allows (as you said) a clean syntactic
separation between starting the PID file handler and continuing it.

It does bring up a question, though. What if pid_file_handler() needed
to be broken into three or more pieces, thus containing multiple yield
statements? Does only the first one return a continuation object, which
can be called repeatedly to continue after each yield like this?

sub init_server(:$pid_file, ...) {
# ...
my &more_pid_stuff := pid_file_handler($pid_file);



# ...

Or does each yield produce a fresh new continuation object like this?

sub init_server(:$pid_file, ...) {
# ...
my &write_pid := pid_file_handler($pid_file);

my &fold_pid := write_pid();

my &spindle_pid := fold_pid();

# ...

(Note that I assume you can simply ignore the returned object if you
don't plan to continue the operation any more, without raising a

Certainly the first version has less visual clutter, so I tend to lean
that way by default. But the second design would allow one to create a
tree of partial executions, by calling any earlier continuation object
again. That's a very powerful concept that I don't want to give up on.

Supporting both feels like it might be an adverb on the invocation
(possibly with a frosty sugar coating available). It would be nice to
support invoking a continuation in "ratcheting" and "forgetful" modes.



Search Discussions

Discussion Posts


Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 10 of 14 | next ›
Discussion Overview
groupperl6-language @
postedJan 1, '09 at 8:34p
activeJan 27, '09 at 1:03a



site design / logo © 2021 Grokbase