# 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))
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]
```

## 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:

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

## 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
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
```