Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active September 3, 2019 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xliff/d426039cc162e1cb84d1b7f8067fe9fb to your computer and use it in GitHub Desktop.
Save Xliff/d426039cc162e1cb84d1b7f8067fe9fb to your computer and use it in GitHub Desktop.
Proposal for Storing Signatures for Reuse as Sub/Method Argument Declarators in Perl6.

Right now Perl6 is lacking one significant feature that is avaiable in C and othe languages: the ability to store a sub specification. Not now that I am not talking about anonymous subroutines, but the declaration of such.

In C, a function pointer looks like this:

gboolean
(*GstBusFunc) (GstBus * bus,
               GstMessage * message,
               gpointer user_data)

Right now it would help, if Perl6 could borrow from this to help improve code reuse and hygiene.

Consider the following anonymous sub declaration:

my $lambda = -> $arg1, $arg2, $arg3, $arg4 --> List { ($arg1, $arg2, $arg3, $arg4) »*» &returnsASmallerList }

What $lambda is supposed to do is irrelevant for this discussion, however the first line is:

my $lambda = -> $arg1, $arg2, $arg3, $arg4 --> List {

Currently in Perl6, if that signature is to be reused, the programmer will have to type that declaration over again...every single time it is to be used. In situations where callback are important, this is non-optimal.

NativeCall, I'm looking at you.

What I propose is the ability to leverge Perl6's abilty to store Signature definitions and put them to use to resolve this situation.

FunctionDefinition

The details of this have yet to be ironed out, and much of what I propose is up for discussion (including the name!), I believe that a future version of perl would benefit from the following. The ability to store a Signature in a special kind of container that can be used in anonymous sub definitions. Consider:

my &^FourArgList = :($arg1, $arg2, $arg3, $arg4 --> List);

sub a:&^FourArgList {
  ($arg1, $arg2, $arg3, $arg4) »*» &returnsASmallerList
}

Yes, I am leveraging the use of a Signature object here. The Perl6 language spec is well designed, I'm just proposing a small addition.

The above approch is cleaner and much more maintainable. Consider when we are doing more than using one sub:

sub a ($arg1, $arg2, $arg3, $arg4 --> List) {
  ...
}

sub b ($arg1, $arg2, $arg3, $arg4 --> List) {
 ...
}
...
sub z ($arg1, $arg2, $arg3, $arg4 --> List) {
  ...
}

Is much more difficult to maintain than:

my &^FourArgList = :($arg1, $arg2, $arg3, $arg4 --> List);

sub a:&^FourArgList {
  ...
}

sub b:&^FourArgList{
 ...
}
...
sub z:&^FourArgList {
  ...
}

...especially if something happened and speficications changed requiring a(), b() up to z() to change their argument or return type.

This also touches on specific aspects of NativeCall, even though it is not part of the Perl6 language spec.

Right now, significant use of callbacks, especially in light of modern C libraries where such things are used extensively, suffer from the same maintanability problem. Consider this NativeCall sub definition:

sub native-sub(
  Pointer $object,
  Str $name,
  &handler (Int, Int, Int, Pointer --> Struct),
)
  returns native-type
  is export
  is native(&native-lib)
  { * }

It suffers from the same issues illustrated, above. It would also benefit from a FunctionDeclarator:

my &^NativeCallback = :(Int, Int, Int, Pointer --> Struct);
sub native-sub(
  Pointer $object,
  Str $name,
  &^NativeCallback
)
  returns native-type
  is export
  is native(&native-lib)
  { * }

Full disclosure: I am currently writing several projects that deal with exactly this situation, and I would greatly appreciate the ability to cut down my current efforts in maintaining them. Such a feature would help greatly, in that regard.

I know that this proposal is missing a lot of details and has its issues that can be discussed. However, I am hoping that it is sufficient enough to open a dialog about a feature that I think is missing from the language.

Thank you for your consideration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment