We will work on the assumption #33 is implemented and a lack of a return type means inference, not void.
A function statement defines a function name and an implementation:
fn hello(a: int) { 1 }
A function expression (lambda) is the same but without a name.
let hello: T = fn(a) { 1 };
Param types may be omitted if the assignment target has a function type.
A function type expression looks like this:
let T = fn (a: int) -> float;
When this is placed before the let hello line, semantic analysis will assign the function into the type T (this function prototype) and actualize the parameters a and the return type into a float.
We will disallow this for now
let hello = fn(a) { 1 }; // what is the type
We will disallow this for now
fn hello(a) { 1 } // what type is `a`
The function statements may appear either module level or block level. The former allowing use-before-declare.
Milestone: 0.2.0.
I could see
let T = fn (a: int) -> float;
being
let T = (a: int) -> float;
but I don't feel strongly about it. Potential future bikeshed.