Functions

Unlike in most functional programming languages, functions are not first-class citizens in Melodeon. They cannot be passed as arguments into other functions (that is, Melodeon doesn’t have higher-order functions). Instead, they are always defined at the “top level”.

Here’s how to define a function in Melodeon:

def function_name(arg_1: type_1, arg_2: type_2, ..., arg_n: type_n) = expression

Argument type annotations are mandatory, as explained in the section on type inference. The function body must be a single expression.

Examples:

def double(x: Nat) = x * 2
def poly(x: Nat) = x ** 2 + quadruple(x) + 8 def quadruple(x: Nat) = loop 2 do x <- x + x return x
def to_point(x: Nat, y: Nat) = Point{x: x, y: y} struct Point { x: Nat, y: Nat }

As we see from these examples, the order of definitions does not matter in Melodeon. Furthermore, function and variable names must start with a lower-case letter and are idiomatically written in snake_case.

Optionally, you can annotate the output type, like this:

def double(x: Nat) : Nat = x * 2 def tuplify(x: Nat, y: Nat) : Point = Point{x: x, y: y}

Currently, all functions must be defined in .melo files; support for function definitions in the REPL is forthcoming!