Function types

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.

Simple function types

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))

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

def Dec(n as Int) as Int
  return n - 1

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)
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 = [1] as Array<Int>
app = a.append
Print(a)      -- [1, 5]

Default arguments values and varargs

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:

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).

Types Function and Type

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

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