I'm glad to see someone else bringing up named parameters in the discussion
about sub prototypes; I was trying to get my thoughts straight on the subject
but still had some confusions.

If there was a prototyping change that allowed named variables in the prototype to be 
automatically made into lexicals inside the sub, that's great for the
writer of the sub, but it doesn't really help the person calling the sub
that much.

With short parameter lists, positionals are fine.  With long,
partially-optional, subject-to-future-change parameter lists, I like the
CGI.pm/MIME::Entity style of calling them with a hash.  This has two
problems:  firstly, if you want to support both positional and named parameters,
you have to do funky things inside your sub; and secondly, you won't be
able to use the new prototyping at all, since all named-parameter subs would
end up prototyped:

        sub foo ( %params ) {

But it seems to me (and evidently the author of this RFC) that since you
*have* the names of the parameters in the sub prototype, the compiler should
be able to translate a named-parameter call into a positional call, using the
names and type-checking that's in the prototype.

I am not sure about the suggested "foo( x = 20, y = 40 )" call syntax though.
x and y look like functions to me (since they're barewords and not on
the left of an "=>" ), and even with $x and $y instead it still doesn't look
right -- $x and $y aren't variables in the scope in which the sub is called,
they're lexicals inside the sub itself.

I almost don't think named parameters are worth having unless you can supply
hashes or hashrefs to the subs; otherwise, you can't build parameter lists
outside the sub call itself.

On the other hand, the conflict with positional parameters using real hashes
is obviously there, and even using a single hashref is problematic.

One way might be to have a prototype marker that says "this function uses
named parameters, not positionals", and then have that function callable with
a simple hash; elements mentioned in the prototype parameter list that exist
in the suppliedhash are converted to lexicals as if they were positional
parameters.  I kind of like this, except that I can't think of a good syntax
for the prototype part.  This splits all functions into positional and
named-parameter types.

Another option would be to have the prototyping system include a marker
that meant something like "if you have only a single hashref supplied as
an argument, use the values inside as the parameters instead of using it
as a positional parameter", so you could then call subs declared like that
with:

        foo( +{ a => 1, b => 2 } );

However, that prevents you from having a hashref as the first argument
to those subs, and it does not generalise to every function, just those
that decide they should be callable that way.  Also, requiring anonymous
hash constructors in every named-parameter call is annoying.

Yet another way would be the way CGI.pm does it (I think), by looking at
the first parameter to see if it starts with an '-' and if so, treat them
as named parameters.  Again, this prevents you from supplying an argument
with a leading '-', so I don't think it's a very good idea.

Given that none of these are very appealing, maybe this could be addressed
better in a standard module.

        use NamedProtos;

        sub foo ( %params ) {
                # standard (new) prototype format supplied as string.
                die unless named_protos( 'x : int, y : int', %params );
        }

This doesn't allow you to automatically make lexicals with the names of
the parameters, but it could let you do the type-checking part, at least.

Maybe someone's got another RFC lined up that has a Really Good answer to
all of this, but I thought since the subject was raised I'd say what I'd been
thinking about the problem.

-- 
Jacob Davies
[EMAIL PROTECTED]

Reply via email to