On Thu, Oct 02, 2003 at 01:59:26AM -0600, Luke Palmer wrote:
: So, I must ask, what does this do:
: 
:     sub foo() {
:         return my $self = {
:             print "Block";
:             return $self;
:         }
:     }
:     
:     my $block = foo;
:     print "Main";
:     $block();
:     print "End";
: 
: That is, the block returns from a function that's not currently
: executing.
: 
: Will the output be: a)
: 
:     Can't 'return' from closure Block

It can't in general be determined at compile time whether the dynamic
scope contains the original sub entry, so this one won't fly.  Note also that
a given return does not just return from a particular subroutine, but a
particular subroutine invocation.  When the closure is generated, the return
throws a control exception that is specific about which invocation of foo()
is to be returned from.

: b)
: 
:     Main
:     Block
:     Can't 'return' from closure Block
: (just like (a) but runtime)

And if that particular invocation is not in the outer dynamic scope, it
fails just like any uncaught exception, so I expect this is close to
the correct answer.  The whole point of doing this with control exceptions
is so that we can say things like

    sub foo() {
        bar { return }
    }

and know that the return is going to return from the current sub, even if 
the closure being passed to bar() is interpreted off somewhere else.  So
return is an invariant regardless of whether bar() is a built-in or not.

: c)
: 
:     Main
:     Block
: 
: (the block's return returns from the main program, or whatever function
: is currently executing)

To be consistent, that would return from bar() rather than foo()
in my previous example.  That would not be what we want return to do.

: d)
: 
:     Main
:     Block
:     Main
:     Block
:     Main
:     Block
:     ...
: 
: (the block closes over the function's return continuation)
: 
: (a) and (b) both sound pretty good.  (c) is a very bad idea, as it's
: very subtle, breaks return type safety, introduces unexpected control
: flow, etc.  We'll leave those responsibilites to C<leave> :-)
: 
: Maybe (d) is the way we slip in continuations without anyone noticing.
: It's the only one of these possibilites that works intuitively with, eg.
: "grep".  It still seems like it might too easily introduce subtle bugs. 

If we force novices to think about continuations, we will have
destroyed Perl as we know it.  Continuations will be need to be
carefully hidden in Perl 6, and available only by explicit request.

: Is there another meaningful possibility that I didn't cover?  I've heard
: Smalltalk has something equivalent to the sub/block distinction; what
: does it do?

Dunno about Smalltalk.  But I see sub/return as a *lexically* scoped
contract to do what the user expects, even when that contract has to
be enforced by run-time chicanery like control exceptions.

By the way, sorry I haven't be more communicative lately, but I spent
most of the last two months in the hospital, where there's no email
access.  Had a benign tumor chopped out of my stomach, and there were
complications.  Full recovery is expected, any month now.  But for the
time being I'm tied to an IV pole pumping calories into my intestines
until I learn to eat again.  So please don't expect me to come to any
conferences any time soon...

Larry

Reply via email to