develooper Front page | perl.perl5.porters | Postings from October 2022

Re: Named argument syntax (was Re: PSC #049 2022-01-07)

Thread Previous | Thread Next
From:
Ovid
Date:
October 8, 2022 13:18
Subject:
Re: Named argument syntax (was Re: PSC #049 2022-01-07)
Message ID:
CA+M4CHuN-8Zw+-s6xf-SkajvnO2X1cubduE7yHz_Vo0vGmQxRw@mail.gmail.com
On Fri, Oct 7, 2022 at 6:04 PM Paul "LeoNerd" Evans <leonerd@leonerd.org.uk>
wrote:

> > I'd expect :@bar to be a syntax error. But note that in a separate
> > proposal, a \@ary parameter auto-dereferences and aliases a passed
> > array ref, as in
> >
> >         sub foo(\@numbers) { say "@numbers" }
> >         foo([1,2,3]); # prints "1 2 3"
> >
> > This can be combined separately with named parameters, giving
> >
> >         sub foo(\:@numbers) { say "@numbers" }
> >         foo("numbers => [1,2,3]); # prints "1 2 3"
>
> My thoughts:
>
>   sub named(:$x, :$y)     # looks nice
>
>   sub no_slurpy(:@nums)   # should be banned
>
>   sub dereffed(\@values)  # again looks nice
>
> However,
>
>   sub named_deref(:\@x)   # I think I'd prefer this spelling
>
> To my eye, `:\@arr` looks and feels a bit better than `\:@arr` does.
> Since we're banning `:@arr`, we learn to avoid a colon next to an at or
> percent sign. It also fits better with what you'd pass in from the
> callsite
>
>   my $result = named_deref\@values_for_x);


First, I think that \:@foo is troublesome because then we're going to have
to explain, for named parameters, that you prefix them with a colon except
when ... and having to remember multiple rules leads to confusion. So
:\@foo seems
cleaner because it leads to single, clear rule:

"Rule 1: Name parameters always begin with a colon."

That seems unambiguous.

That being said, :\@foo compounds Perl's reputation for linenoise. Can we
come up with a rule to avoid this? My first thought is:

"Rule 2: named parameters are scalars, with the scalar constrained to an
array or hash reference, if needed."

With that, no need to include extra punctuation:

    sub foo( $bar, :@baz, :%quux ) { ... }
    # Only legally called via variants of:
    foo( bar => $bar, baz => \@array, quux => \%hash );

Of course, bar can be an aref or href. Only baz and quux are constrained. I
think this fits quite well with Perl's current semantics.

Thus, you only have two rules for named parameters and (I think) they're
consistent. It also removes the gross :\% or \:% in the signature.

I wonder if later we can extend the calling syntax to use a leading colon
for consistency:

    foo( :$bar, :@baz, :%quux );

Each argument is passed to their corresponding parameter without
list flattening. (I assume they're not aliased, but copying could be
expensive and we don't have copy-on-write).

That being said, it means you've coupled the argument names to the
parameter names. I don't know if that's a bad thing, but it might make life
painful for a maintainer who wants to change a variable name to be more
descriptive, but leave the name of the key unchanged (so as to not alter
the interface). But even that can be deal with:

        sub foo( $bar, :@baz, :%quux ) {
          my @useful_name = @baz;
          ...
      }

Best,
Curtis "Ovid" Poe
--
CTO, All Around the World
World-class software development and consulting
https://allaroundtheworld.fr/

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About