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

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

Thread Previous | Thread Next
From:
Darren Duncan
Date:
January 22, 2022 08:46
Subject:
Re: Named argument syntax (was Re: PSC #049 2022-01-07)
Message ID:
018852f4-46da-9a85-499b-0d97e9673c81@darrenduncan.net
On 2022-01-21 10:37 p.m., Darren Duncan wrote:
> I didn't say it in my first post, but something I was thinking about how this 
> could all be implemented internally...
> 
> Internally, the arguments for a sub call are implemented by an ordered 
> collection, an array or arrayref or essentially as it is now, with 1 collection 
> element per argument, in the same order as the calling code called the sub, but 
> each element is now a simple struct which indicates whether it is a positional 
> or a named argument, and in the case of named, what parameter name it indicates.
> 
> Or we can do something else, but the point is that natively an argument list is 
> represented by something which cleanly represents both positional and named 
> arguments.
> 
> Optionally or if necessary this struct is represented to user code as some new 
> fundamental simple data type, which then lets Perl code have a way to represent 
> an argument list as a collection that it can pass around or build or read 
> dynamically etc similarly to how can with @_ now given how that's an array, and 
> similarly to how Raku has types such as Capture or whatever for representing 
> argument lists.

To further explore the matter of native language support for routines that can 
take either positional arguments or named arguments or a combination of both...

Various programming languages do this in different ways and there are a number 
of potential options for Perl to adopt.

The common feature of any languages I have looked at is that at least 
conceptually they are the same, in that each routine conceptually takes TWO 
argument lists, which is 0..N positional parameters represented by an ordered 
set such as an array, plus 0..M named parameters represented by an unordered set 
of name-value pairs such as a dictionary/hash.

Behind the scenes that representation could be used literally pairing a Perl 
array aka @_ with a Perl hash, maybe it could be called %_ if that wasn't 
already in use for some other purpose.  The pair could be wrapped in some other 
type representing a single thing having both kinds of arguments, I believe Raku 
calls this combined thing a Capture.

For your information, there is an alternate approach I have chosen to use with 
my Muldis Object Notation (MUON) / Muldis Data Language (MDL), which is in 
summary to only have named arguments as the only true kind, and to fake 
positional arguments in terms of special argument names.  Where Raku has 
Capture, I have Tuple which is the data type representing argument lists, as 
well as all typical concepts of either positional or named tuples.

If Perl were to adopt the same approach as MUON, then it means in effect 
entirely swapping out the @_ array for a plain regular Perl hash, and all the 
existing Perl operators and routines for hashes would work with it.

How I fake positional arguments with named ones is to use single-character 
strings such that the string of just the Unicode codepoint zero, "\x{0}", is the 
first positional argument, the string of just codepoint one, "\x{1}", is the 
second, and so on.

Strictly speaking that approach has limits, as you can't have more positional 
arguments than there are Unicode code points, which if you're being strict is in 
one sense about 1.1M, though its much lower as its not valid to use the numbers 
from the surrogates, so maybe you get a few thousand.

But practically speaking I designed around the expectation that one wouldn't 
actually use more than 32 positional parameters, which corresponds to the main 
block of 31 ASCII non-printing control characters plus the space, and assuming 
that named parameters would usually just have names with printable characters, 
and so code point 32 and up are printable.

In this context, all parameters whether conceptually positional or named can be 
expressed in a named form, but the common shorthand exists where positional 
syntax implicitly assigns the appropriate "names" left to right, so these are 
equivalent:

     ("\x{0}": 29, "foo": 95)

     (29, "foo": 95)

Note that for normalization, a single-character name is treated as a positional 
parameter if and only if all other single-character names from zero thru that 
one exist in the collection; any time there is a gap, its just treated as 
regular named, so for example, this one is treated as having zero positional 
parameters:

     ("\x{1}": 99)

Also it is an error to have an explicit parameter name in the same collection 
literal that maps to a positional that is implicitly named, such as this:

     (42, "\x{0}": 25)

... similarly to having the same name appear explicitly twice.

Personally I would anticipate Perl would use the array plus hash approach as 
that is probably the least surprising, however there are other ways it COULD be 
done as I illustrated.

But the implementers should do whatever they feel is best as usual.

-- Darren Duncan

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