develooper Front page | perl.perl6.language | Postings from May 2004

Re: A12: Required Named Parameters Strike Back!

Thread Previous | Thread Next
Dov Wasserman
May 4, 2004 03:01
Re: A12: Required Named Parameters Strike Back!
Message ID:
Long-time lurker, first time poster. Dittos, kudos, etc.

Back on the topic of required named parameters, I think John Siracusa's
initial post did a good job of separating the two concepts of parameter
mandate (required vs. optional) and parameter designation (by position vs.
by name). Each of these dimensions can be very useful, and IMHO should be
independently supported by the language.

An earlier A6 issue which I wasn't crazy about (once John's post got me
thinking about it) is that the parameter zone marker '+'  on +$foo denotes
two different things:

    1. parameter $foo must be passed by name only (and not by position)
    2. parameter $foo is optional

I imagine we all agree that most named-only parameters will be declared to
be optional in practice. That is likely why Larry designed the '+' marker to
declare both meanings. We also now seem to have consensus that required
named parameters should somehow be supported by the language; at
compile-time when possible (subs), or at run-time when not
([multi-]methods). However, I don't think the single '+' character should
denote both meanings.

What we are really trying to say with a "named-only" parameter is that this
parameter has no numeric positional place; it only has a name. The '+'
symbol to me implies something which is required. In Perl 6, it generally
coerces its unary operand to a numeric context. Given that the '+' zone
marker in A6 means "this parameter is optional and it is has no numeric
position", this visual marker is either highly misleading, nonsensical, or

Since in the rest of Perl 6, the '~' operator involves string
representation, perhaps the standard +$foo marker should really be ~$foo:
i.e., $foo only has a (string) name, not a numeric position. Thus ~$foo
would mean exactly what +$foo currently means: $foo may only be passed by
name, and it is optional.

Declaring a parameter to be named-only would now require a different syntax.
For your parametric perusal pleasure:

    1. sub foo($req1, ?$opt1, ~$optNamedOnly, ~$reqNamedOnly is req) {...};
    2. sub foo($req1, ?$opt1, ~$optNamedOnly, +$reqNamedOnly) {...};
    3. sub foo($req1, ?$opt1, ~?$optNamedOnly, ~$reqNamedOnly) {...};
    4. sub foo($req1, ?$opt1, $optNamedOnly is named, $reqNamedOnly is named
is req) {...};

Version 1 simply replaces '+' with '~' for psychological/visual purposes,
and keeps all named-only parameters as optional, unless declared otherwise
by the "is req" trait. It has the advantage of being closest to the current
spec. It has the disadvantage of silently switching the parameter mandate
default from required to optional when you declare a parameter's designation
as named-only. You can override the mandate with "is req", but this is
inconsistent with "$req1" being already required by default.

Version 2 uses '~' for "optional named only parameter", and transforms '+'
to mean "required named-only parameter". It has the advantage of keeping all
zone markers to 1 character without additional traits. It has the
disadvantage of using '~' and '+' to mean two things that are somewhat
similar and somewhat different.

Version 3 uses '~' for all named-only parameters, which by default are
required (like positional parameters). You must insert a '?' to make the
parameter optional. There is no '+' zone marker (at least for these
purposes). This version has the advantage of using the same '?' token for
the same purpose as the other marker(s). I also think it is a visual
advantage to have all named-only params declared with the same marker, '~'
in this syntactic version. It has the disadvantage of needing 2 chars '~?'
(or '?~', but IMHO not either) to declare the common case of "optional
named-only", and only 1 char for the less common "required named-only". This
is poor Huffman coding. However, I remain confident that Larry can devise a
better Huffman-coded scheme than I have which still addresses the main
points. ;-)

Version 4 basically throw its hands up and decides that the semantics we
want are too complex to denote in a single character. It is simple, but
verbose. Probably the various '~/?/+' markers translate into similar
'named/optional/required' traits that we can always declare explicitly if we
want to.

OK, I just wanted to throw some ideas in the air. Whether they end up being
required reading or unnecessary needling is up to you. I will not take a
position on the matter.

-Dov Wasserman

"Larry Wall" <> wrote in message
> On Mon, Apr 19, 2004 at 01:44:53PM -0400, John Siracusa wrote:
> : On 4/19/04 1:30 PM, Larry Wall wrote:
> : > On Mon, Apr 19, 2004 at 01:14:57PM -0400, John Siracusa wrote:
> : > : I know we are running out of special characters, but I really,
really think
> : > : that required named parameters are a natural fit for many common
APIs.  A12
> : > : has reinforced that belief.  Save me, Dami-Wan Wallnobi, you're my
> : > : hope...
> : >
> : > Well, actually, we saved you last summer when we decided to make +
> : > mean that the parameter must be named.
> :
> : ...named and required, or named and optional?  IOW, is this all true?
> :
> :     sub foo(+$a, +$b) { ... }
> :
> :     foo();          # compile-time error!
> :     foo(1, 2);      # compile-time error!
> :     foo(a => 1, 2); # compile-time error!
> :     foo(a => 1);    # compile-time error!
> :
> :     foo(a => 5, b => 7); # ok
> :     foo(b => 1, a => 2); # ok
> Well, no, we're still stuck at run-time validation of that.  In the case
> of methods you can't really do anything else anyway, generally speaking.
> For subs, we could make the compiler pay attention to something in the
> declaration:
>     sub foo(+$a is req, +$b is req) { ... }
>     sub foo(+$a = fail, +$b = fail) { ... }
> But I still don't think it rates a strange character of its own.
> Possibly there's something going on with multi subs and invocants.
> I'm not sure what 6.0.0 will make of a declaration like:
>     multi sub foo(+$a, +$b: +$c) { ... }
> since we've told the Parrot people they don't have to worry about
> anything but positional parameters for 6.0.0.
> But none of this has much bearing on BUILD routines, which are shielded
> from positional semantics anyway by the fact that .bless() doesn't
> take any extra positional parameters.
> Larry

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About