I think a partial unification of objects and code refs in userspace
is going to be a nice features.
Closures allow people to put arbitrary complexity into a very simple
api that is, in OO terms, just one method (the actual function
call).
Consequentially the closure may never reveal any information about
it's actual behavior.
I think the convenience of closures can be enhanced by allowing
closures to declare that certain captured variables are in fact
instance data (see below for ideas on how).
A trivial example:
my @callback_list;
$some_object.register_callback(sub { for @callback_list -> &f { f() } });
sub add_callback (&f) {
push @callback_list, &f;
}
This allows to register a number of callbacks to $some_object using
a simple combinator.
The problem is that without writing the add_callback api we lose the
ability to modify this list, effectively forcing us to create an
api.
Perhaps a better approach is to create a callbackregistry class:
class CallbackRegistry {
has @callbacks;
method trigger {
for @callbacks -> &f { f() };
}
method make_meta_callback {
sub { self.trigger }; # interesting question here... can we close over lexical subs like self?
}
}
Then we make a callback registry, and do something like
$some_object.register_callback( $registry.make_meta_callback());
Essentially what this is doing is reimplementing the concepts of
closures in OO terms.
This layer could be removed by doing something like this:
# first we define the API of the closure
class ListOfCallbacksCallback isa Closure {
has @callbacks;
}
my @callbacks;
sub { @callbacks } but ListOfCallbacksCallback; # not quite sure of this
Essentially this would overload sub capture, and make it into a
constructor call of some sort. Variable renaming facilities would be
nice, but even just a capture containing the body and all the
closed over variables would be cool.
This keeps things concise and lightweight, but does add the ability
to inspect (via a well defined api) what a closure is encapsulating,
etc.
--
Yuval Kogman <nothi...@woobling.org>
http://nothingmuch.woobling.org 0xEBD27418
my $x = 42;
&f := sub {
have $.x;
say $x;
...
}
say &f.x;
Here I'm using the plural possesive to indicate that $x is shared, in
the same sense that "our" is indicating something that's shared, only
in this case it's a shared lexical rather than a shared package variable.
Then you'd just use some variant of ordinary introspection to find
these methods.
But I've probably missed your meta-point entirely...
Larry
> my $x = 42;
> &f := sub {
> have $.x;
> say $x;
> ...
> }
> say &f.x;
hmm... That looks nice.
Maybe even this makes sense:
sub {
have $.x;
method blah { }
}
Conversely, I'd also like to be able to do Closure, which is a
subrole of Code with a constructor. Or rather, an instantiated Code
is a proto of Closure ;-)