Functions and Calls
One namespace, two call forms
There is one function namespace, and f(x, a) and x.f(a) are the same call. The method form passes the receiver as the first argument. It never runs anything stored in the value: f always resolves to a built-in or a host function.
toUpperCase(user.name) // => "ADA"
user.name.toUpperCase() // => "ADA"
sum(prices) // => 15
prices.sum() // => 15
round(3.14159, 2) // => 3.14
(3.14159).round(2) // => 3.14Chaining methods reads left to right, like the pipelines of other languages:
items.map(.price * .qty).sum().toFixed(2) // => "18.00"length is a property, not a function; has and try are special forms. The full list of built-ins is in Built-in Functions.
Overloads
Built-in functions are overloaded on parameter types. includes works on text and on lists; min takes a list or several numbers; sum adds numbers or durations. When argument types are known, the overload is chosen by the checker; otherwise it is chosen at run time from the kinds of the arguments.
"hello".includes("ell") // => true
[1, 2, 3].includes(2) // => true
min(4, 9, 2) // => 2
prices.min() // => 2
[hours(1), minutes(30)].sum() // => PT1H30MA call that matches no overload is an error:
round("a") // error: NO_OVERLOADSpread arguments
...list expands a list into arguments:
max(...prices) // => 9
max(1, ...prices, 20) // => 20A spread argument cannot be used with a function that takes a lambda.
null arguments
A null argument selects an overload whose parameter accepts null. If none does and the null is the first argument (the receiver), the call is a NULL_RECEIVER error in either call form, or null when the call uses ?.. A null in any later position is a NO_OVERLOAD error, and ?. does not change that: it only skips a call on a null receiver.
user.nickname.toUpperCase() // error: NULL_RECEIVER
toUpperCase(user.nickname) // error: NULL_RECEIVER
user.nickname?.toUpperCase() // => null
(user.nickname ?? "").toUpperCase() // => ""
isEmpty(user.nickname) // => true
user.name?.startsWith(user.nickname) // error: NO_OVERLOAD
user.name.startsWith(user.nickname ?? "") // => trueFunctions such as isEmpty, toString, and type accept null, and the calendar functions accept null as the time zone (meaning UTC).
Host functions
The host can add functions with typed parameters. They are called exactly like built-ins, in either form. A host function with the same name as a built-in replaces the built-in for that environment, so built-ins added in future releases never change the meaning of an existing host's expressions. See Host Functions.
Evaluation order
Operands, arguments, and lambda invocations are evaluated left to right, one at a time, including in async mode. Higher-order built-ins call their lambda in list order and stop as soon as the result is known (some, every, find, ...).