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

A6 - no mandatory named arguments

7 views
Skip to first unread message

Nicholas Clark

unread,
Mar 15, 2003, 6:16:49 PM3/15/03
to perl6-l...@perl.org
If I've understood A6 correctly there are 6 types of argument to subroutines:
invocant, mandatory positional parameters, optional positional parameters,
optional named parameters, slurpy hash and slurpy array.

How come there seems to be no way to specify mandatory named parameters?
I'm not sure that *I*'d ever want to write subroutines that insist that
they are called with named parameters, and that 1 or more named parameters
are present, but it seems slightly strange to me that there seems to be
no built in way to specify this. If people find they do want to do this,
without a built in way, surely they're either each going to roll their own
(different) ways of extending the compile time syntax, or do it at run time
and so not benefit from compile time error detection.

Or would such a feature be a complete white elephant?

Nicholas Clark

Uri Guttman

unread,
Mar 15, 2003, 7:20:58 PM3/15/03
to Nicholas Clark, perl6-l...@perl.org
>>>>> "NC" == Nicholas Clark <ni...@unfortu.net> writes:

NC> If I've understood A6 correctly there are 6 types of argument to
NC> subroutines: invocant, mandatory positional parameters, optional
NC> positional parameters, optional named parameters, slurpy hash and
NC> slurpy array.

NC> How come there seems to be no way to specify mandatory named
NC> parameters? I'm not sure that *I*'d ever want to write
NC> subroutines that insist that they are called with named
NC> parameters, and that 1 or more named parameters are present, but
NC> it seems slightly strange to me that there seems to be no built in
NC> way to specify this. If people find they do want to do this,
NC> without a built in way, surely they're either each going to roll
NC> their own (different) ways of extending the compile time syntax,
NC> or do it at run time and so not benefit from compile time error
NC> detection.

apoc6:

A hash declaration like *%named indicates that the %named hash
should slurp up all the remaining named arguments (that is,
those that aren't bound explicitly to a specific formal
parameter).

that tells me that you can use named arguments to fill in the required
positional (formal) params.

and in the calling section it says:

After the positional argument part, you may pass as many named
pairs as you like. These may bind to any formal parameter named
in the declaration, whether declared as positional or
named. However, it is erroneous to simultaneously bind a
parameter both by position and by name. Perl may (but is not
required to) give you a warning or error about this.

so it seems you can pass only named args and if you don't pass in enough
to fill all the required positional args, it can be an error. it could
even be a compile time one since the named args canbe checked against
the names of the positional params.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Damian Conway Perl Classes - January 2003 -- http://www.stemsystems.com/class

Mlazzaro

unread,
Mar 15, 2003, 8:32:41 PM3/15/03
to Uri Guttman, Nicholas Clark, perl6-l...@perl.org
Uri Guttman wrote:

> >>>>> "NC" == Nicholas Clark <ni...@unfortu.net> writes:
>
> NC> How come there seems to be no way to specify mandatory named
> NC> parameters? I'm not sure that *I*'d ever want to write
>

> apoc6:
> A hash declaration like *%named indicates that the %named hash
> should slurp up all the remaining named arguments (that is,
> those that aren't bound explicitly to a specific formal
> parameter).
>
> that tells me that you can use named arguments to fill in the required
> positional (formal) params.

Yeah, I read that as saying that *%named will slurp up any named ('looks like a
pair') arguments that have names not explicitly specified by the signature
parameters, but I don't *think* that implies anything about whether or not the
names you _do_ specify are actually required to exist. So I have to agree, my
reading of A6 is that named parameters are _always_ treated as optional... the
only way to specify _required_ parameters are as positionals. Design team,
help?


> and in the calling section it says:
>
> After the positional argument part, you may pass as many named
> pairs as you like. These may bind to any formal parameter named
> in the declaration, whether declared as positional or
> named. However, it is erroneous to simultaneously bind a
> parameter both by position and by name. Perl may (but is not
> required to) give you a warning or error about this.
>
> so it seems you can pass only named args and if you don't pass in enough
> to fill all the required positional args, it can be an error. it could
> even be a compile time one since the named args canbe checked against
> the names of the positional params.

So you can only specify a named argument by name, but you can specify a
positional argument either by position or name. So yes, technically you _can_
pass a required (positional) parameter by name, but you wouldn't be _required_
to pass it by name.

sub foo($pos, +$zap) {...}

foo('a', zap => 'b'); # OK
foo( pos => 'a', zap => 'b'); # OK too
foo( zap => 'b', pos => 'a'); # OK

foo('a', 'b'); # ERROR; $zap must be named, not positional
foo( zap => 'b' ); # ERROR; $pos is not bound (?)
foo( zap => 'b', 'a' ); # ERROR; wrong way round
foo( 'a', pos => 'a'); # ERROR; simultaniously bound by position and name
foo( 'a', zap => 'b', zap => 'c' ); # ?

(Not sure about the exact error messages on those ones... I'm hoping they can be
descriptive, and that the second error there doesn't just try and assign the
string 'zap' to $pos.)

So my reading is that it's not possible to specify 'required' named parameters,
unless we're completely missing something. My first impulse is that it's not a
big deal, because who's gonna do that? My second impulse is... well... if I
were writing a big library with big, hairy methods, and wanted to *require* the
use of names for all params because the signatures are just too baffling
otherwise, I can sortof see wanting that... If, for example, you are a purist
who believes _all_ sub parameters should be named, we might want Perl to
nonjudgementally support that particular neurosis. Bleah, dunno.

MikeL

Larry Wall

unread,
Mar 15, 2003, 9:13:31 PM3/15/03
to perl6-l...@perl.org
On Sat, Mar 15, 2003 at 05:32:41PM -0800, mlazzaro wrote:
: So my reading is that it's not possible to specify 'required' named parameters,

: unless we're completely missing something. My first impulse is that it's not a
: big deal, because who's gonna do that? My second impulse is... well... if I
: were writing a big library with big, hairy methods, and wanted to *require* the
: use of names for all params because the signatures are just too baffling
: otherwise, I can sortof see wanting that... If, for example, you are a purist
: who believes _all_ sub parameters should be named, we might want Perl to
: nonjudgementally support that particular neurosis. Bleah, dunno.

Your reading is correct. It's possible to force the issue at run time, at least:

sub foo(+$req = die 'You must supply a "req =>" argument') {...}

or maybe

sub foo(+$req = MUST) {...}

where "MUST" could be something even more magical, possibly even
recognized by the compiler, just as $CALLER::_ could be. But I'm
not terribly interested in supporting that particular neurosis.

Larry

Uri Guttman

unread,
Mar 15, 2003, 11:05:59 PM3/15/03
to perl6-l...@perl.org
>>>>> "LW" == Larry Wall <la...@wall.org> writes:

LW> On Sat, Mar 15, 2003 at 05:32:41PM -0800, mlazzaro wrote:

LW> : So my reading is that it's not possible to specify 'required'
LW> : named parameters, unless we're completely missing something. My
LW> : first impulse is that it's not a big deal, because who's gonna
LW> : do that? My second impulse is... well... if I were writing a
LW> : big library with big, hairy methods, and wanted to *require* the
LW> : use of names for all params because the signatures are just too
LW> : baffling otherwise, I can sortof see wanting that... If, for
LW> : example, you are a purist who believes _all_ sub parameters
LW> : should be named, we might want Perl to nonjudgementally support
LW> : that particular neurosis. Bleah, dunno.

LW> Your reading is correct. It's possible to force the issue at run
LW> time, at least:

LW> sub foo(+$req = die 'You must supply a "req =>" argument') {...}

LW> or maybe

LW> sub foo(+$req = MUST) {...}

LW> where "MUST" could be something even more magical, possibly even
LW> recognized by the compiler, just as $CALLER::_ could be. But I'm
LW> not terribly interested in supporting that particular neurosis.

but if you declare required positionals and don't pass them all in even
by name, the compiler will detect that now via the signature. if the
caller knows the order and passes them in that way, and the module doc
says to pass them by name, then caller emptor. if the sub is documented
to be all pass by name and you don't do that, then you are to
blame. there is no need for more B&D here, just let the compiler check
the names passed in against the list in the sig.

this means that you have a more perl5 like experience IMO:

sub foo( $a, $b, $c ) { ... }

foo( 1, 2, 3 ) ;

foo( a => 1, c => 3, b => 4 ) ;

@args = ( a => 3, c => 4 ) ;
foo( b => 3, *@args ) ;

@args = ( a => 3 ) ;
foo( b => 3, *@args, c => 5 ) ;

i think all of those should work (AFAIK they are ok with apoc6).

i like the ability to build up the pairs in an array or hash and
splatting that in the call. one good use is when you have extra
arguments optionally added to the arg list.

too often in p5 you see the args assigned to hash and then parsed out
with tedious runtime code or a module or sub that does it. i created
such a beast which describes all the attributes of an object with list
of hashes that have a name, required flag, default, and other
things. having the compiler do more of this checking would make it
easier to debug and remove a lot of runtime overhead.

having the required params in the first zone (positional) and then the
optional named args makes it also easier to manage required vs
optional. my current design has a whole attribute description flag
dedicated to 'required' and it only checks at runtime.

when you pass in named args with a splatted hash/array then you have to
defer checking to runtime if any required params aren't filled in
explicitly in the call. so the last two cases above lose some/all
compile time checking.

one issue is that you pass $b by position and the others by name. only
the earlier ones can be passed by position and later ones by name.

0 new messages