Skip to content

Commit 3e898f2

Browse files
committed
Add section about parameter type
1 parent 241abe5 commit 3e898f2

File tree

1 file changed

+55
-12
lines changed

1 file changed

+55
-12
lines changed

spec/05-functions.md

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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.7 "Parameter binding".
25+
* Parameter binding happens, explained in section 5.8 "Parameter binding".
2626
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.8 "Function body".
28+
in section 5.9 "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".
@@ -45,8 +45,8 @@ see [Chapter 13: Macros](13-macros.md).
4545
## 5.2 Optional parameters
4646

4747
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.
48+
declare it _optional_, so that a call to the function will still succeed even
49+
if the parameter is not passed.
5050

5151
A parameter can be declared optional using the `@optional` annotation:
5252

@@ -263,7 +263,37 @@ fnWithNamedRestArgument(x => 1, y => 2); // { y => 2 }
263263
fnWithNamedRestArgument(x => 1); // {}
264264
```
265265

266-
## 5.7 Parameter binding
266+
## 5.7 Parameter type
267+
268+
A parameter can be associated with a type, in which case the argument is type
269+
checked against the provided type during parameter binding. That is, the
270+
expression `arg is T` must evaluate to a truthy value, or the parameter binding
271+
will fail with (at the latest) a runtime error.
272+
273+
There are two ways to declare a type with a parameter. The first uses a `@type`
274+
annotation:
275+
276+
```
277+
func fnWithTypedParameter(@type(Int) x) {
278+
say x;
279+
}
280+
281+
fnWithTypedParameter(42); // 42
282+
fnWithTypedParameter("hi"); // <error: type mismatch>
283+
```
284+
285+
The second way uses an infix `:` syntax:
286+
287+
```
288+
func fnWithTypedParameter(x: Int) {
289+
say x;
290+
}
291+
292+
fnWithTypedParameter(42); // 42
293+
fnWithTypedParameter("hi"); // <error: type mismatch>
294+
```
295+
296+
## 5.8 Parameter binding
267297

268298
During function invocation, when arguments have been passed to a function for
269299
invocation, and before the function body can run, an environment is constructed in which the function body later runs.
@@ -279,36 +309,47 @@ The first step breaks down into the following smaller steps:
279309
* Assert that the number of positional arguments does not exceed the number of
280310
(required and optional) positional parameters, or that there's a positional
281311
rest parameter declared in the parameter list. If not, signal an exception.
312+
* If the positional rest parameter has a type, assert that the type is
313+
`Array<T>` for some `T`.
282314
* Assert that, for each required named parameter, there is a named argument of
283315
that name. If not, signal an exception.
284316
* Assert that all named arguments that were passed have a corresponding named
285317
parameter, or that a named rest parameter is declared in the parameter list.
286318
If not, signal an exception.
319+
* If the named rest parameter has a type, assert that the type is
320+
`Dict<string, V>` for some `V`.
287321

288322
At this point, we know that parameter binding won't fail because not enough
289323
arguments were passed for the required parameters, or too many arguments were
290324
passed that rest parameters weren't present to absorb.
291325

292326
* For each required positional parameter, bind it to the corresponding
293-
positional argument (of which we just checked there are enough).
327+
positional argument (of which we just checked there are enough). If the
328+
parameter has a type, check the argument against the type.
294329
* For each optional positional parameter, bind it left-to-right to the
295330
corresponding positional argument, the value of the parameter default
296-
expression if present, or `none` if not.
331+
expression if present, or `none` if not. If the parameter has a type, check
332+
the bound value against the type.
297333
* If there is a positional rest parameter, make an array of the remaining
298334
positional arguments, and bind the positional rest parameter to this array.
335+
If the positional rest parameter has a type `Array<T>`, check each remaining
336+
positional argument against `T`.
299337
* For each required named parameter, bind it to the corresponding named
300-
argument (which we just asserted exists).
338+
argument (which we just asserted exists). If the parameter has a type, check
339+
the argument against the type.
301340
* For each optional named parameter, bind it left-to-right (in the parameter
302341
list) to the corresponding named argument, the value of the parameter default
303-
expression if present, or `none` if not.
342+
expression if present, or `none` if not. If the parameter has a type, check
343+
the bound value against the type.
304344
* If there is a named rest parameter, make a dictionary of the remaining named
305345
arguments (name and argument), and bind the named rest parameter to this
306-
dictionary.
346+
dictionary. If the named rest parameter has a type `Dict<string, V>`, check
347+
each remaining named argument against `V`.
307348

308349
The resulting environment is the one that will be used when running the
309350
function body.
310351

311-
## 5.8 Function body
352+
## 5.9 Function body
312353

313354
The function body runs normally, except that the environment it runs in is
314355
extended with the parameters bound to either arguments or parameter defaults.
@@ -317,10 +358,12 @@ Inside a function body, it is also valid to use the statement `return <expr>;`
317358
which has the effect of evaluating `<expr>` and immediately terminating the
318359
running of the function body, returning the value that results to the caller.
319360

320-
## 5.9 Returning from a function
361+
## 5.10 Returning from a function
321362

322363
A value is returned from the function, either by explicitly executing a
323364
`return` statement in the function body, or by statement execution falling off
324365
the end of the function body. In the latter case, the value returned from the
325366
function is `none`.
326367

368+
## 5.11 Function return type
369+

0 commit comments

Comments
 (0)