@@ -22,10 +22,10 @@ the time of evaluating the call expression, these steps happen:
2222 _ arguments_ .
2323* The ` call ` method of the invocation protocol is invoked, with an array of
2424 the arguments.
25- * Parameter binding happens, explained in section 5.8. If successful,
26- this results in an extended environment.
25+ * Parameter binding happens, explained in section 5.7 "Parameter binding".
26+ If successful, this results in an extended environment.
2727 * The function's body is run in the extended environment. This is explained
28- in section 5.9 "Function body".
28+ in section 5.8 "Function body".
2929 * Eventually, control might return normally, in which case a value is also
3030 returned. This value is then the value of entire call expression. This is
3131 explained in section 5.10 "Returning from a function".
@@ -44,36 +44,229 @@ see [Chapter 12: Macros](12-macros.md).
4444
4545## 5.2 Optional parameters
4646
47- xxx ` @optional ` syntax
47+ A parameter is _ required_ by default, but there are two different ways to
48+ declare it _ optional_ , meaning that a call to the function will still succeed
49+ even if the parameter is not passed.
4850
49- xxx ` ? ` syntax
51+ A parameter can be declared optional using the ` @optional ` annotation:
52+
53+ ```
54+ func fnWithOptParam(@optional param) {
55+ say param;
56+ }
57+
58+ fnWithOptParam(42); // 42
59+ fnWithOptParam(); // none
60+
61+ func fnWithReqParam(param) {
62+ say param;
63+ }
64+
65+ fnWithReqParam(42); // 42
66+ fnWithReqParam(); // <error: too few arguments>
67+ ```
68+
69+ Or it can be declared optional using the ` ? ` suffix on parameters:
70+
71+ ```
72+ func fnWithOptParam(param?) {
73+ say param;
74+ }
75+
76+ fnWithOptParam(42); // 42
77+ fnWithOptParam(); // none
78+ ```
79+
80+ Using both forms at once is valid but redundant, and might be flagged by a code
81+ linter:
82+
83+ ```
84+ func fnWithOptParam(@optional param?) {
85+ say param;
86+ }
87+
88+ fnWithOptParam(42); // 42
89+ fnWithOptParam(); // none
90+ ```
91+
92+ In a function declaration with both required and optional parameters, all the
93+ optional parameters must be declared after all the required ones.
5094
5195## 5.3 Parameter defaults
5296
53- xxx ` @default(expr) ` syntax
97+ _ Parameter defaults_ are expressions that are evaluated if (and only if) an
98+ argument was not passed. There are two different ways to declare a parameter
99+ default.
100+
101+ The first way uses an annotation:
102+
103+ ```
104+ func fnWithParamDefault(@default(5) param) {
105+ say param;
106+ }
107+
108+ fnWithParamDefault(42); // 42
109+ fmWithParamDefault(); // 5
110+ ```
111+
112+ The second way uses an infix ` = ` syntax:
113+
114+ ```
115+ func fnWithParamDefault(param = 5) {
116+ say param;
117+ }
118+
119+ fnWithParamDefault(42); // 42
120+ fmWithParamDefault(); // 5
121+ ```
122+
123+ Using both syntaxes for the same parameter results in a declaration-time error:
124+
125+ ```
126+ func fnWithParamDefault(@default(1) param = 2) { // <error: two defaults>
127+ say param;
128+ }
129+ ```
130+
131+ Giving a parameter a default implies that the parameter is optional. Declaring
132+ a parameter both optional and having a default is allowed, but the default is
133+ enough.
134+
135+ ```
136+ func fnWithOptionalParamWithDefault(@optional @default(1) param) { // fine
137+ }
138+
139+ func fnWithOptionalParamWithDefault(@default(2) param?) { // fine
140+ }
141+
142+ func fnWithOptionalParamWithDefault(@optional param = 3) { // fine
143+ }
144+
145+ func fnWithOptionalParamWithDefault(param? = 4) { // fine
146+ }
147+ ```
148+
149+ Because the parameter name itself indicates the point at which the parameter
150+ is declared and thus visible, one difference between the annotation form and
151+ the ` = ` form is that the parameter itself is bound and visible in the ` = ` form
152+ but not in the annotation form:
54153
55- xxx ` = ` syntax
154+ ```
155+ func fnUsingParamInDefault(x = x) { // fine
156+ }
157+
158+ func fnUsingParamInDefault(@default(x) x) { // <error: no such variable x>
159+ }
160+ ```
56161
57162## 5.4 Rest parameter
58163
59- xxx ` @rest ` syntax
164+ A function can handle an excess of arguments being passed by declaring a _ rest
165+ parameter_ , which will bind to an array containing the excess arguments. There
166+ are two syntaxes for declaring a rest parameter.
167+
168+ The first syntax uses a ` @rest ` annotation:
169+
170+ ```
171+ func fnWithRestParam(x, y, z, @rest r) {
172+ say r;
173+ }
174+
175+ fnWithRestParam(1, 2, 3); // []
176+ fnWithRestParam(1, 2, 3, 4, 5); // [4, 5]
177+ ```
178+
179+ The second syntax uses a prefix ` ... ` on the parameter:
180+
181+ ```
182+ func fnWithRestParam(x, y, z, ...r) {
183+ say r;
184+ }
60185
61- xxx ` ... ` syntax
186+ fnWithRestParam(1, 2, 3); // []
187+ fnWithRestParam(1, 2, 3, 4, 5); // [4, 5]
188+ ```
189+
190+ Using both forms at once is valid but redundant, and might be flagged by a code
191+ linter:
192+
193+ ```
194+ func fnWithRestParam(x, y, z, @rest ...r) {
195+ say r;
196+ }
197+
198+ fnWithRestParam(1, 2, 3); // []
199+ fnWithRestParam(1, 2, 3, 4, 5); // [4, 5]
200+ ```
201+
202+ A parameter which is not a rest parameter is called an _ individual_ parameter.
62203
63204## 5.5 Named parameter
64205
65- xxx ` @named ` syntax
206+ A _ named_ parameter indicates that the corresponding operand should be written
207+ as a key/value pair, using the same syntax as for dictionary key/value pairs:
208+
209+ ```
210+ func fnWithNamedParameter(@named param) {
211+ say param;
212+ }
213+
214+ fnWithNamedParameter(param => "hi"); // hi
215+ fnWithNamedParameter("hi"); // <error: missing named param "param">
216+ ```
217+
218+ There is only one syntax for declaring named parameters: the above ` @named `
219+ annotation syntax.
220+
221+ A parameter which is not named is called _ positional_ , as it is identified by
222+ its position in the list of parameters.
223+
224+ In a function declaration with both positional and named parameters, all the
225+ named parameters must be declared after all the positional ones.
226+
227+ By default, a named parameter is required, but it can be used together with the
228+ ` @optional ` annotation (or the ` ? ` syntax) to make it an optional named
229+ parameter.
230+
231+ Similarly, a named parameter can be given a default, using either the
232+ ` @default ` annotation, or the ` = ` syntax.
66233
67234## 5.6 Named rest parameter
68235
69- xxx it's a combination of ` @named ` and ` @rest ` (in any order)
236+ A named parameter which is also declared as a rest parameter is a _ named rest
237+ parameter_ : it collects up any named arguments that were passed but don't have
238+ a corresponding argument into a dictionary of excess named arguments.
239+
240+ ```
241+ func fnWithNamedRestArgument(
242+ @named x,
243+ @named @rest rest, // @rest @named also works
244+ ) {
245+ say rest;
246+ }
70247
71- xxx or ` @named ` and ` ... `
248+ fnWithNamedRestArgument(x => 1, y => 2); // { y => 2 }
249+ fnWithNamedRestArgument(x => 1); // {}
250+ ```
72251
73- ## 5.8 Parameter binding
252+ Any syntax for declaring the parameter a rest parameter works:
253+
254+ ```
255+ func fnWithNamedRestArgument(
256+ @named x,
257+ @named ...rest,
258+ ) {
259+ say rest;
260+ }
261+
262+ fnWithNamedRestArgument(x => 1, y => 2); // { y => 2 }
263+ fnWithNamedRestArgument(x => 1); // {}
264+ ```
265+
266+ ## 5.7 Parameter binding
74267
75268During function invocation, when arguments have been passed to a function for
76- invocation, and before the function body can run, an environment is constructed in which to run the function body.
269+ invocation, and before the function body can run, an environment is constructed in which the function body later runs .
77270
78271This happens in two steps: first, making sure that there is an argument for
79272each required parameter and a parameter for each passed argument, and second,
@@ -115,7 +308,18 @@ passed that rest parameters weren't present to absorb.
115308The resulting environment is the one that will be used when running the
116309function body.
117310
118- ## 5.9 Function body
311+ ## 5.8 Function body
312+
313+ The function body runs normally, except that the environment it runs in is
314+ extended with the parameters bound to either arguments or parameter defaults.
315+
316+ Inside a function body, it is also valid to use the statement ` return <expr>; `
317+ which has the effect of evaluating ` <expr> ` and immediately terminating the
318+ running of the function body, returning the value that results to the caller.
319+
320+ ## 5.9 Returning from a function
119321
120- ## 5.10 Returning from a function
322+ A value is returned from the function, either by explicitly executing a
323+ ` return ` statement in the function body, or by "falling off the end" of the
324+ function. In the latter case, the value returned from the function is ` none ` .
121325
0 commit comments