The more I think about it, the less I like it. I see now that the
reason for the construct was to support
temp &foo.wrap(blahblah);
which seems like an odd duck otherwise.
But the restoring ability of the TEMP block has nothing to do with the
return value handle. And just how does that work? Does the TEMP block
it called in its natural sequence (returning a closure) and then stored
in some hidden place that the caller then looks for it if and only if
the temp keyword was used, in which case it sets up a LEAVE trait on the
enclosing block. The secret hiding place is a faux return value, and
you're introducing a whole new mechanism for no other purpose.
You could just say
my $handle is leave { .restore }
= &foo.wrap(blahblah);
which leaves (ha!) the communication back to the caller with the return
value where it belongs, and doesn't introduce anything new at all.
By the way, I don't like it that
$handle = &foo.wrap(blahblah);
is restored by
&foo.unwrap($handle);
with $handle being specific to &foo anyway. It means you have to name
the function again, and offers the possibility of making an error. It
should be
$handle.unwrap
or
$handle.restore
with no possibility of mismatching the symbols.
Is wrapping a routine really so special that it needs a fancy mechanism
to unwrap it at the end of a scope? I imagine lots of things may want
that, such as closing files and windows. And why not the possibilities
of doing it on success or on failure only, or different things on each?
Putting in the function, with a special syntax to hook into it, is very
limiting.
If the "is leave" trait is too verbose, then think of it as leaving
something for people to do with macros.
--John
John M. Dlugosz dhcgnd702-at-sneakemail.com |Perl 6| wrote:
S06 "Temporization", along with 'temp' variables, defines a TEMP block.
Do we really need such a thing? It appears to be a LEAVE block with another
level of indirection. Hmm, that is, the body of the TEMP block executes at its
normal place at run-time, unlike the episodic blocks it resembles; the return
value is appended to the LEAVE trait.
It seems difficult to generate a closure at run time (as opposed to just
cloning one specified at compile time), so I wonder why you would need to do
that.
It also makes me think about traits on cloned closures or specific instances of
routines. But again, I don't think we really need to have individual instances
of routines have their own traits distinct from the Routine object itself,
since you can accomplish that using variables subject to cloning within the
closure in the trait (e.g. the LEAVE trait).
In short, can we drop
TEMP {{ $next = $curr }}
?