dave_the_m has posted a long and very comprehensive thread to perl5-porters in which he outlines his plans for subroutine signatures. The plan is to get a consensus on the syntax of the various features and then to implement them over the next year. The goal is to have subroutine signatures out of experimental status by Perl 5.36. Whatever breaking of backwards compatibility with the existing (experimental) subroutines is necessary should go into 5.32.

I have mostly copied the Synopsis section of each mail here, and I really encourage you to look at the mails themselves which contain far more discussion of the proposed behaviours.

The separate threads are:

Jumbo Signatures extensions discussion - the top level thread

Here is a contrived example of a signature which demonstrates many of the proposals. Some of it will make more sense after each proposal has been read.

sub foo ( $self, # parameter declarations starting with '?' examine, # but don't consume any further arguments: ?*@args, # @args is set to the equivalent of @_ with one # arg shifted; i.e. like a slurpy but peeking ahead # and not actually consuming any args; the '*' means # that each @args element is aliased to a passed arg ?$peek_a, # $peek_a is bound to next arg but without consuming + it ??$has_a, # $has_a is set to true if there's an argument for $ +a $a, # normal scalar parameter ?{ print $a },# embedded code block - runs code; doesn't shift arg +s Dog $spot, # works the same as 'my Dog $spot' $b :shared, # you can use normal variable attributes $c :ro, # at compile time, $c in lvalue context croaks \@ary, # aliases @ary to a passed array reference \%hash, # aliases %hash to a passed hash reference *$scalar, # aliases $scalar to the next argument # Constraints and coercions: $d!, # croak if $d not defined $e isa Foo::Bar, # croak if $e isn't of that class $f is Int where $_ > 0, # croak if $f not a positive integer $x = 0, # a default value $y?, # short for $y = undef \@array?, # short for \@array = [] :$name1 = 0, :$name2 = 0, # consume name-value pairs (name1 => ..., name2 => . +...) @rest # slurp up any remaining arguments ) { .... }

Parameter Attributes

sub f ($x :foo, $y :bar(baz) bar2(baz2), ...) { ... }

analogous to:

my $x :foo; my $y :bar(baz) bar2(baz2);

Perl should support parameter attributes.

What exactly should the semantics be? Lets first review the current syntax as applied to 'my' declarations:

my ($x, $y) :foo(foo_arg) :bar(bar_arg);

is roughly equivalent to

use attributes (); my ($x,$y); attributes->import(, __PACKAGE__, \$x, "foo(foo_arg)", "bar(bar_ar +g)"); attributes->import(, __PACKAGE__, \$y, "foo(foo_arg)", "bar(bar_ar +g)");

Named Parameters

sub foo ( $pos1, # positional parameter; consumes 1 arg $pos2, # positional parameter; consumes 1 arg :$name1, # named parameter, consumes ("name1", value) arg +pair :$name2, # named parameter, consumes ("name2", value) arg +pair @rest, # consumes all unrecognised name/value pairs ) { ... }

This seems a popular feature request: give Perl 5 something similar to Perl 6's named parameters.

Querying Parameters

?$x peek ahead to the next arg ??$x peek ahead and see if there is a next arg ?@a peek ahead and copy all remaining args ?%h peek ahead and copy all remaining key/val arg pairs ?{ code } execute some code without consuming any args

Sometimes you want to find out some extra information about the arguments and the state of argument processing. With @_ available, this can be done, if messily; if @_ isn't populated (see the "@_ Suppression" thread), then it becomes harder/impossible, unless some other mechanisms are added.

@_ suppression

@_ will not be set, unset or localised on entry to or exit from a signatured sub; it will still be the @_ of the caller. But any use of @_ within the lexical scope of sub a sub will warn.

Aliasing and Read-only variables

sub foo { # the lexical vars $a, @b and %c are aliased to the things poi +nted # to by the reference values passed as the first three argumen +ts: \$a \@b, \%c, # $d is aliased to the fourth arg: *$d, # $e is aliased to the fifth arg, but at compile time, any us +e # of $e in lvalue context within this lexical scope is a compi +le # time error: *$e :ro, # the elements of @f are aliased to any remaining args, # i.e. a slurpy with aliasing ...: *@f # .. or a slurpy hash; every second remaining arg is aliased t +o # the hash's values: *%g ) { ... }

Type and Value Constraints and Coercions

sub f( $self isa Foo::Bar, # croak unless $self->isa('Foo +::Bar'); $foo isa Foo::Bar?, # croak unless undef or of tha +t class $a!, # croak unless $a is defined $b is Int, # croak if $b not int-like $c is Int?, # croak unless undefined or in +t-like $d is PositiveInt, # user-defined type $e is Int where $_ >= 1, # multiple constraints $f is \@, # croak unless array ref $aref as ref ? $_ : [ $_ ] # coercions: maybe modify the +param ) { ...};

It seems that people express a desire to be able to write something like:

sub f (Int $x) { ... }

as a shorthand for for something like:

sub f ($x) { croak unless defined $x && !ref($x) && $x =~ /\A-?[0-9]+\Z/; ....; }

Similarly people want

sub f (Some::Arbitrary::Class $x) { ... }

as a shorthand for

sub f ($x) { croak unless defined $x && ref($x) && $x->isa(Some::Arbitrary::Class); ...; }

Furthermore, there are also Perl 6 generic constraints:

sub f ($x where * < 10*$y) { ... }

Scope and Ordering

We need to determine and document how the various parts of a signature behave as regards to lexical scope, visibility, tainting and ordering of things like default expressions and constraints.

dave_the_m proposes for lexical scoping that:

sub f($a, $b, $c, ... ) { BODY; }

Is logically equivalent to:

sub f { my $a = ....; my $b = ....; my $c = ....; ....; BODY; }

In particular, each parameter element is independent taint-wise, and each parameter variable has been fully introduced and is visible to default expressions and the like in further parameters to the right of it.

Miscellaneous suggestions

This last post contains are a few random suggestions that people have made at various times.


In reply to Jumbo Signatures extensions discussion by Corion

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.