Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Interrogating closures

6 views
Skip to first unread message

Yuval Kogman

unread,
Nov 30, 2006, 6:48:37 AM11/30/06
to perl6-l...@perl.org
Hi,

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

Larry Wall

unread,
Nov 30, 2006, 12:13:42 PM11/30/06
to perl6-l...@perl.org
If I follow what you're saying (and this is by no means a certainty :)
I would tend to look more for a declarative solution than a callback
solution, so I'm imagining that any closure could have a declarator
that explicitly captures an outside lexical and makes it available
as an attribute. I don't quite want to use "has" though, but it
something possessive.

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

Yuval Kogman

unread,
Nov 30, 2006, 12:56:23 PM11/30/06
to perl6-l...@perl.org
On Thu, Nov 30, 2006 at 09:13:42 -0800, Larry Wall wrote:

> 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 ;-)

0 new messages