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)

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.

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.

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.
