Alore functions are also objects. You can pass them as arguments to functions and store them in data structures like any objects. The type system has separate types for functions.
A simple function type has the form def (A1, ..., An) as R. Here Ai are argument types and R is the return value type. If you omit R, it defaults to void.
Here is a simple example that defines a higher-order function Twice that calls the argument function twice:
def Twice(n as Int, f as def (n) as Int) as Int return f(f(n)) end
We can now call the function; we need to pass a callable object as the second argument:
def Inc(n as Int) as Int return n + 1 end def Dec(n as Int) as Int return n - 1 end Print(Twice(3, Inc)) -- Ok; 5 Print(Twice(3, Dec)) -- Ok; 1
You can also use anonymous functions:
Twice(3, def (n as Int) as Int return n * 2 end) -- 12 (3 * 2 * 2)
Type objects have also function types; their type depends on the signature of create. The return value type is derived from the class. Example:
class C def create(n as Int) ... end end var f as def (n as Int) as C f = C -- Ok
Bound methods also have function types:
var app as def (Int) var a =  as Array<Int> app = a.append app(5) Print(a) -- [1, 5]
Function types can have arguments with default values and variable-length argument lists. Default argument expressions are never present in types; they are only included in function definitions. Examples:
- Type def (Int, Int=) accepts 1 or 2 integer arguments.
- Type def (Int, *Int) accepts 1 or more integer arguments.
A function type is compatible with a more restrictive function type. For example, def (Int, Int=) is compatible with both def (Int) and def (Int, Int) (but not vice versa).
Every function definition is also a subtype of std::Function; every type object is also a subtype of std::Type. Since these are simple types, they cannot represent argument types or return value types. You need to cast the value to dynamic if you want to call it:
def Next(n as Int) as Int return n + 1 end var f = Next as Function -- Ok f(2) -- Error: cannot call value of type Function (f as dynamic)(2) -- Ok
The type std::Type supports the is operation and is often useful for that purpose:
var t = Int as Type 1 is t -- Ok