source: doc/proposals/named-parameters.md @ 1b770e40

Last change on this file since 1b770e40 was 1f11818, checked in by Andrew Beach <ajbeach@…>, 5 months ago

Updated the named parameter proposal. Adding sections (or paragraphs) for syntax options, the current status and where it is placed in compilation.

  • Property mode set to 100644
File size: 10.3 KB
Line 
1Named Parameters
2================
3An examination of the possibility of adding named parameters to Cforall.
4Named parameters allow arguments to be passed and matched to a parameter by
5their name instead of their position in the argument list.
6
7A comparison of positional and named argument passing:
8    make_position(getWidth(), getHeight());
9    make_position(.x = getWidth(), .y = getHeight());
10
11The example of a Python style printer using optional named parameters:
12    printp("Error:", errorCode, .file=serr, .endl="");
13
14Variations of this feature can be found in various languages:
15+   Python - Keyword Arguments
16+   Swift - Argument Labels
17+   Ada - Named Association
18+   C - Designators (limited)
19
20Status of Proposal
21------------------
22This proposal is "an examination", there are still issues to solve. Including
23syntax, the exact rules of how forward declarations and definitions must
24relate. It does break through a major problem C had, in that names of
25parameters are not consistent. By using C parameters as positional-only
26parameters so that does not cause issues.
27
28Overview of New Features
29------------------------
30In terms of code written, this feature interacts with the following:
31
32Function Applications and Arguments:
33When a function is applied and passed arguments those arguments must be
34provided either as `Positional Arguments` or `Named Arguments`.
35
36Positional arguments use the existing C syntax and named arguments could
37reuse member designator syntax (`.NAME = EXPR` in an argument list).
38
39Function Declarations and Parameters:
40When a function is declared its parameters may be defined as `Positional
41Parameters` or `Named Parameters`. Unlike with arguments, this is not an
42either or thing, parameters are actually in three groups `Positional Only`,
43`Named Only` and `Positional or Named`. In addition, all parameters can
44be `Required Parameters` or `Optional Parameters`.
45
46Current C syntax should be used for positional parameters. New syntax will
47be needed for named-only or named-or-positional parameters. Something like,
48`TYPE .NAME` (a dot at the front of the parameter name, to reflect the
49argument form).
50
51Current Cforall does have some support for optional parameters and default
52arguments. An optional parameter is declared by proving it with a default
53argument (putting `= EXPR` after the parameter declaration). There is also
54syntax for explicitly requesting the default argument is used (`@`).
55
56As an extension, we could allow array designators (`[ POSITION ] =`) as a way
57to explicitly give the position of an argument. This is not an existing
58Cforall feature, nor directly related to named parameters, but it is an
59extension of C semantics that fits in this area.
60(I would actually recommend against it at this time, parameter lists should
61not be so long that this is useful.)
62
63Function Pointers
64-----------------
65Function pointers do not need to support named parameters, in the same way
66they do not support optional parameters. (You can write an optional parameter
67in a function pointer, but it is ignored.) There could be some way to convert
68or cast between the two forms, but in practice, the types of functions where
69named parameters are useful have very little overlap with those that you
70would pass to a higher order function or use as an assertion.
71
72Argument Matching
73-----------------
74How are arguments connected to parameters. This will become part of the
75overload resolution process, luckily it is a pretty simple straight forward
76pass fail check so does not effect cost. This covers all the features being
77considered, but most can cleanly be removed.
78
79Note that matching arguments to parameters is tied up into matching calls
80with definitions, and requires arguments to be resolved, and so has to happen
81within the resolver.
82
83First, the positional parameters have to be sorted out.
84
85Undesignated arguments are positional arguments, if one appears at the front
86of the argument list it is the 0 positional argument, otherwise it must
87follow another positional argument and it goes into the next position. It is
88an error for an undesignated argument to appear after a named argument.
89
90Array designated arguments are positional arguments. The constant expression
91is evaluated and the result is the position of the parameter it is matched
92with.
93
94The same process is way simpler with named arguments, as all are labeled.
95Member designated arguments are named arguments. They are matched with the
96parameter with the same name.
97
98The `@` argument can be used anywhere other arguments can be. The parameter
99it is matched with must be an optional parameters and this explicitly requests
100that the default argument be used.
101
102Then we can just check to make sure no parameter is provided/matched with an
103argument more than once, and that every required parameter is provided
104exactly once. If any arguments could not be matched to a parameter, it is an
105error.
106
107Note that there are no special rules for positional-or-named parameters, they
108can just be used in either case.
109
110Backwards Compatibility
111-----------------------
112All parameters and arguments in C code can treated as (required and)
113positional, except for initializers which are optional and use designators.
114
115Initializers and C designators always consider the underlying parameter's
116position the important part. The designator moves the position in the
117parameter list forward or backward. If an argument is not designated, it is
118put the next position after the previous argument (or the first position if
119it is the first argument).
120
121It should be noted that this is actually more permissive than most languages.
122Other named parameter system enforce that all positional arguments come
123before all named arguments.
124
125However, we could translate this using optional and named-or-positional
126parameters. Removing the ability to have undesignated arguments follow
127a member designated arguments is required for named only parameters, doing
128the same for named-or-positional for a consistent interface.
129
130C also allows chained designators, nested initializers and descending into and
131out of recursive initializers automatically as the beginning or end of those
132sections. In the context of a member/element initializer, the system does
133have enough information to do this, because the target types are fixed by the
134type being initialized.
135
136These should be supported in the C escape initializer (`@=`), but cannot be
137generalized to function calls (not even initializers we resolve as functions)
138because of overloading.
139
140Syntax Options
141--------------
142The syntax suggested above both does not work and may be incomplete. It was
143good enough for the initial descussion but will need some further work.
144
145The issue with the above syntax is that `TYPE .NAME` can look like a
146qualified type to the parser. Considering how wide spreak the qualified type
147syntax is, it could be changed. Here are some syntax suggestions:
148
149Named Argument: `.NAME = EXPR`
150Named (Required) Parameter: `TYPE .NAME`
151Named (Optional) Parameter: `TYPE .NAME = EXPR`
152
153The first suggestion is an attempt to use C designator syntax as the name
154syntax. A named parameter is now a generialization of designators. The
155parameters are added into a function's parameter list.
156
157        `@NAME = EXPR` | `TYPE @NAME` | `TYPE @NAME = EXPR`
158        `?NAME = EXPR` | `TYPE ?NAME` | `TYPE ?NAME = EXPR`
159
160Some other characters that could be used in the same syntax. The `@` symbol
161hints at some location/address. Peter was just excited about `?` but it is an
162little used symbol and parses at this time. This does weaken the connection
163with designators, which was the main advantage of the designator like syntax.
164
165Named Argument: `NAME: EXPR`
166Named Parameter: `NAME: TYPE NAME0` | `TYPE NAME:`
167
168Another bit of C syntax we could try to adapt to named parameters are labels.
169We reuse the label syntax used at the statement level at the expression level
170to note where (with which parameter) this expression goes.
171
172This syntax (the first option for the named parameter) is also has an example
173of a possible (but not popular) feature where the parameter name (the
174identifier used inside the function) and the parameter label (the identifier
175used at the call site) are independent.
176
177        `PARAMS;PARAMS` | `;PARAMS`
178
179Another way to describe the type of parameters is by dividing the parameter
180list into sections. Here we replace a `,` separator between two parameters,
181with a single (per parameter list) `;` that marks the end of the positional
182parameters. The argument syntax would have to be borrowed from some other
183example (such as the designator one, where the parameter is the problematic
184one for the parser), possibly with another `;` separator to add context.
185Also, the `;` separator can appear at the beginning of the parameter list as
186well if all parameters are positional.
187
188Named Argument: `NAME @= EXPR`
189Named Parameter: `TYPE NAME @= EXPR`
190
191Another syntax to modify is assignment, with a special "assign to parameter"
192operator (although structurally it
193
194        `NAME := EXPR` | `TYPE NAME := EXPR`
195
196Like with the variations of the designator-like syntax, the separator could
197be changed out, so that symbol can be used as the identifying feature of the
198named argument.
199
200The incompleteness is that most of these just have one more parameter
201declaration. That is, there is only syntax for positional-or-named parameters
202or named-only parameters, so far it has been named-only. Positional-only
203parameters are "locked" to the C syntax for compatability reasons. Supporting
204both cases gives additional flexibility and could be done by combining two
205of the above syntax (or by altering one).
206
207        void call(int position, char .position_or_name = a; double .name = b);
208
209Note, that C-style autogenerated constructors would still be positional or
210named parameters for compatability.
211
212Run-time Implementation
213-----------------------
214The underlying code must be translated into simple C code that does not use
215these parameters or arguments.
216
217For this purpose, we do use the ordering of all parameters, writing them
218out in the order they appear in the declaration.
219Note that the programmer still does not have to (and sometimes cannot)
220interact with the order of parameters, but the compiler will still use them.
221Here it boils down all the named forms down to positional code. This is the
222run-time efficient way to implement it. Other forms of argument packing, such
223as putting the named arguments into a map, tend to be slower and their
224advantages allow for more dynamic behaviour has a harder time using
225effectively.
Note: See TracBrowser for help on using the repository browser.