Named Parameters
================
An examination of the possibility of adding named parameters to Cforall.
Named parameters allow arguments to be passed and matched to a parameter by
their name instead of their position in the argument list.

A comparison of positional and named argument passing:
    make_position(getWidth(), getHeight());
    make_position(.x = getWidth(), .y = getHeight());

The example of a Python style printer using optional named parameters:
    printp("Error:", errorCode, .file=serr, .endl="");

Variations of this feature can be found in various languages:
+   Python - Keyword Arguments
+   Swift - Argument Labels
+   Ada - Named Association
+   C - Designators (limited)

Status of Proposal
------------------
This proposal is "an examination", there are still issues to solve. Including
syntax, the exact rules of how forward declarations and definitions must
relate. It does break through a major problem C had, in that names of
parameters are not consistent. By using C parameters as positional-only
parameters so that does not cause issues.

Overview of New Features
------------------------
In terms of code written, this feature interacts with the following:

Function Applications and Arguments:
When a function is applied and passed arguments those arguments must be
provided either as `Positional Arguments` or `Named Arguments`.

Positional arguments use the existing C syntax and named arguments could
reuse member designator syntax (`.NAME = EXPR` in an argument list).

Function Declarations and Parameters:
When a function is declared its parameters may be defined as `Positional
Parameters` or `Named Parameters`. Unlike with arguments, this is not an
either or thing, parameters are actually in three groups `Positional Only`,
`Named Only` and `Positional or Named`. In addition, all parameters can
be `Required Parameters` or `Optional Parameters`.

Current C syntax should be used for positional parameters. New syntax will
be needed for named-only or named-or-positional parameters. Something like,
`TYPE .NAME` (a dot at the front of the parameter name, to reflect the
argument form).

Current Cforall does have some support for optional parameters and default
arguments. An optional parameter is declared by proving it with a default
argument (putting `= EXPR` after the parameter declaration). There is also
syntax for explicitly requesting the default argument is used (`@`).

As an extension, we could allow array designators (`[ POSITION ] =`) as a way
to explicitly give the position of an argument. This is not an existing
Cforall feature, nor directly related to named parameters, but it is an
extension of C semantics that fits in this area.
(I would actually recommend against it at this time, parameter lists should
not be so long that this is useful.)

Function Pointers
-----------------
Function pointers do not need to support named parameters, in the same way
they do not support optional parameters. (You can write an optional parameter
in a function pointer, but it is ignored.) There could be some way to convert
or cast between the two forms, but in practice, the types of functions where
named parameters are useful have very little overlap with those that you
would pass to a higher order function or use as an assertion.

Argument Matching
-----------------
How are arguments connected to parameters. This will become part of the
overload resolution process, luckily it is a pretty simple straight forward
pass fail check so does not effect cost. This covers all the features being
considered, but most can cleanly be removed.

Note that matching arguments to parameters is tied up into matching calls
with definitions, and requires arguments to be resolved, and so has to happen
within the resolver.

First, the positional parameters have to be sorted out.

Undesignated arguments are positional arguments, if one appears at the front
of the argument list it is the 0 positional argument, otherwise it must
follow another positional argument and it goes into the next position. It is
an error for an undesignated argument to appear after a named argument.

Array designated arguments are positional arguments. The constant expression
is evaluated and the result is the position of the parameter it is matched
with.

The same process is way simpler with named arguments, as all are labeled.
Member designated arguments are named arguments. They are matched with the
parameter with the same name.

The `@` argument can be used anywhere other arguments can be. The parameter
it is matched with must be an optional parameters and this explicitly requests
that the default argument be used.

Then we can just check to make sure no parameter is provided/matched with an
argument more than once, and that every required parameter is provided
exactly once. If any arguments could not be matched to a parameter, it is an
error.

Note that there are no special rules for positional-or-named parameters, they
can just be used in either case.

Backwards Compatibility
-----------------------
All parameters and arguments in C code can treated as (required and)
positional, except for initializers which are optional and use designators.

Initializers and C designators always consider the underlying parameter's
position the important part. The designator moves the position in the
parameter list forward or backward. If an argument is not designated, it is
put the next position after the previous argument (or the first position if
it is the first argument).

It should be noted that this is actually more permissive than most languages.
Other named parameter system enforce that all positional arguments come
before all named arguments.

However, we could translate this using optional and named-or-positional
parameters. Removing the ability to have undesignated arguments follow
a member designated arguments is required for named only parameters, doing
the same for named-or-positional for a consistent interface.

C also allows chained designators, nested initializers and descending into and
out of recursive initializers automatically as the beginning or end of those
sections. In the context of a member/element initializer, the system does
have enough information to do this, because the target types are fixed by the
type being initialized.

These should be supported in the C escape initializer (`@=`), but cannot be
generalized to function calls (not even initializers we resolve as functions)
because of overloading.

Syntax Options
--------------
The syntax suggested above both does not work and may be incomplete. It was
good enough for the initial descussion but will need some further work.

The issue with the above syntax is that `TYPE .NAME` can look like a
qualified type to the parser. Considering how wide spreak the qualified type
syntax is, it could be changed. Here are some syntax suggestions:

Named Argument: `.NAME = EXPR`
Named (Required) Parameter: `TYPE .NAME`
Named (Optional) Parameter: `TYPE .NAME = EXPR`

The first suggestion is an attempt to use C designator syntax as the name
syntax. A named parameter is now a generialization of designators. The
parameters are added into a function's parameter list.

	`@NAME = EXPR` | `TYPE @NAME` | `TYPE @NAME = EXPR`
	`?NAME = EXPR` | `TYPE ?NAME` | `TYPE ?NAME = EXPR`

Some other characters that could be used in the same syntax. The `@` symbol
hints at some location/address. Peter was just excited about `?` but it is an
little used symbol and parses at this time. This does weaken the connection
with designators, which was the main advantage of the designator like syntax.

Named Argument: `NAME: EXPR`
Named Parameter: `NAME: TYPE NAME0` | `TYPE NAME:`

Another bit of C syntax we could try to adapt to named parameters are labels.
We reuse the label syntax used at the statement level at the expression level
to note where (with which parameter) this expression goes.

This syntax (the first option for the named parameter) is also has an example
of a possible (but not popular) feature where the parameter name (the
identifier used inside the function) and the parameter label (the identifier
used at the call site) are independent.

	`PARAMS;PARAMS` | `;PARAMS`

Another way to describe the type of parameters is by dividing the parameter
list into sections. Here we replace a `,` separator between two parameters,
with a single (per parameter list) `;` that marks the end of the positional
parameters. The argument syntax would have to be borrowed from some other
example (such as the designator one, where the parameter is the problematic
one for the parser), possibly with another `;` separator to add context.
Also, the `;` separator can appear at the beginning of the parameter list as
well if all parameters are positional.

Named Argument: `NAME @= EXPR`
Named Parameter: `TYPE NAME @= EXPR`

Another syntax to modify is assignment, with a special "assign to parameter"
operator (although structurally it

	`NAME := EXPR` | `TYPE NAME := EXPR`

Like with the variations of the designator-like syntax, the separator could
be changed out, so that symbol can be used as the identifying feature of the
named argument.

The incompleteness is that most of these just have one more parameter
declaration. That is, there is only syntax for positional-or-named parameters
or named-only parameters, so far it has been named-only. Positional-only
parameters are "locked" to the C syntax for compatability reasons. Supporting
both cases gives additional flexibility and could be done by combining two
of the above syntax (or by altering one).

	void call(int position, char .position_or_name = a; double .name = b);

Note, that C-style autogenerated constructors would still be positional or
named parameters for compatability.

Run-time Implementation
-----------------------
The underlying code must be translated into simple C code that does not use
these parameters or arguments.

For this purpose, we do use the ordering of all parameters, writing them
out in the order they appear in the declaration.
Note that the programmer still does not have to (and sometimes cannot)
interact with the order of parameters, but the compiler will still use them.
Here it boils down all the named forms down to positional code. This is the
run-time efficient way to implement it. Other forms of argument packing, such
as putting the named arguments into a map, tend to be slower and their
advantages allow for more dynamic behaviour has a harder time using
effectively.
