Langur parameters fall into the following categories.
You can define optional parameters after positional parameters using the assignment syntax to define a default value for them.
val addto = fn(a, b=3) { a + b }
Optional arguments are always passed with the name (using assignment syntax), and positional arguments are never passed with the name.
addto(1)
addto(1, b=12)
Arguments using the name are not order-dependent (as long as they come after positional arguments), and any of them can be left out (except for required parameters by name).
An external name of a parameter by name can be preserved while changing the internal variable name, using the as keyword. An external name specified this way may also be the same as a keyword, since the context makes the meaning clear. The internal name is used within the function and the external name is used in the call.
val x = fn(a as c=123) { a } # a used internally x(c=9) # c used in call
This allows you to change a parameter name internally and not break an API in the process.
Parameters by name should not be confused with argument/parameter expansion, which only applies to positional arguments and parameters.
You can require a parameter that also must use the name (not positional). To do this, use the alias, but do not specify a default value. If you specify a default value, it is an optional parameter.
val x = fn(a as a) { a } # no default value for a; not optional and not positional x(a=9) # a required in call
You can use a ... operator on the last positional argument passed to a function, to expand a list argument into multiple arguments. This precedes any optional arguments passed.
val x = [[21, 7], [42, 14], [96, 21]] zip(x...) # result == [21, 42, 96, 7, 14, 21]
zip(mapX([7], [14, 21], by=fn(x...) { x })...) # result == [7, 7, 14, 21]
You can use the ... operator for parameter expansion. This allows a user-defined function to receive a variable number of positional arguments. The last positional arguments of the function will be placed into a single list. This also allows for setting limits for this expansion (with a default range of 0 to unlimited). A -1 or nothing (such as [2..]) indicates unlimited for this purpose. (The reality, of course, is that there is always a limit, but it is a very high limit.) See the following examples.
val a = fn(x...) { } # accepts 0 or more positional arguments val b = fn(x...[1..9]) { } # accepts 1 to 9 positional arguments val c = fn(x, y...[4]) { } # accepts 5 positional arguments val d = fn(x, y...[2 .. ]) { } # accepts 3 or more positional arguments val e = fn(x, y ...[2 .. 6]) { } # accepts 3 to 7 positional arguments
Argument/parameter expansion does not conflict with parameters by name. Parameters by name always follow positional parameters.
By default, function parameters are immutable.
A future version of langur will likely have options for parameter mutability.
Parameters could be of any type. To restrict a parameter type, use the type name after the parameter name.
fn(x string, y number) { ... } # x and y with explicit type
The possible parts of a parameter, in order, are as follows.
examples of parameter parts in order...
Using parameter expansion does not allow use of the other features at this time (alias, explicit type, or default value).