Dan Sugalski <[EMAIL PROTECTED]> writes:
> At 3:37 PM +0000 1/18/02, Piers Cawley wrote:
>>Michael G Schwern <[EMAIL PROTECTED]> writes:
>>
>>Hmm... making up some syntax on the fly. I sort of like the idea of
>>being able to do
>>
>>     class File;
>>     sub foreach ($file, &block) is Control {
>>         # 'is Control' declares this as a control sub, which, amongst
>>         # other things 'hides' itself from caller. (We can currently
>>         # do something like this already using Hooks::LexWrap type
>>         # tricks.
>>
>>         open my $fh, $file or die $!; POST { close $fh }
>>                while (<FILE>) {
>>             my @ret = wantarray ?? list &block() :: (scalar &block());
>>             given $! {
>>                 when c::RETURN { return wantarray ?? @ret :: @ret[0] }
>>             }
>>         }
>>     }
>>
>>This is, of course, dependent on $! not being set to a RETURN control
>>'exception' in the case where we just fall off the end of the block.
>
> I don't think you'll see $! being set to anything other than real
> errors. Larry may change that, but I'd doubt it. It's more a global
> status than anything else. Exceptions would go elsewhere, I'd hope.

Um... I'm not sure that's how I read the Apocalypse. And if it doesn't
get set how on earth are we going to be able to tell how a block
exited in the case of home rolled looping/iterating constructs where
we're going to want to write:

    sub foo {
        ...
        File.foreach($file_path) {
            ...
            return ($someval) if /some_pattern/;
            ...
        }
    }

and have foo return. 

Maybe we'll have to have something like:

    while (<FILE>) {
        try {
            temp c::RETURN is Error;
            temp c::NEXT is Error;
            temp c::REDO is Error;
            temp c::LAST is Error;
            
            wantarray ?? list &block() :: (scalar &block());
            
            DEFAULT { throw };
        }
   }

Then, because the control structures are temporarily Errors within the
scope of the try block they get thrown up to the first thing that can
handle them. In the case of NEXT/REDO/LAST, that's the while loop, and
in the case of the RETURN, that's the enclosing subroutine. But it
seems kludgy as hell.    

> I personally would like to see subs be taggable as transparent to
> yielding, so if you call a sub, and it calls a sub, that inner sub
> could yied out of the caller if the caller was transparent. Not, mind,
> that the scheme doesn't have issues, but...
>[...]
>>It's also dependent on being able to get continuations from caller
>>(which would be *so* cool)
>
> For some brainwarping version of cool. :)

Hmm... the example I wrote which might possibly have used
continuations got wiped 'cos I realised I wasn't exactly clear on how
they were going to work. But I still think being able to grab a
continuation from up the stack somewhere could be handy, allowing
syntax like:

    &block.call_from($continuation);

Which is sort of nice, and sort of really, really evil. The thing is,
given continuations and $continuation.want (so I can work out what
context the continuation called in...) I can see how to implement it:

    class BLOCK;
    sub call_from ($continuation) {
        given $continuation.want {
            when LIST { $continuation.return(list .yield)   }
            default   { $continuation.return(scalar .yield) }
        }
    }

Of course, I could have got *completely* the wrong end of the stick
about continuations. And this example doesn't do the 'right thing' for
caller, but hey, it's a start.

-- 
Piers

   "It is a truth universally acknowledged that a language in
    possession of a rich syntax must be in need of a rewrite."
         -- Jane Austen?

Reply via email to