mita
mita copied to clipboard
RFC: Functions as first-class types
Introduction
In many languages, functions can be passed to functions. In some, this is even easy. Eclipse Mita should be one of those :)
Current Situation
No support OOTB, only through generated types, but not implemented.
Proposal
Add function references to the language. Closures and currying could follow, but let's not go overboard.
Code Example
fn id(x: int32): int32 {
return x;
}
fn add(x: int32, y: int32): int32 {
return x + y;
}
fn foo(x: int32, f: int32 -> int32) {
print(f(x));
}
fn fooUnicode(x: int32, f: int32 → int32) {
print(f(x));
}
// Parameters could be named?
fn binaryFoo(x: int32, y: int32, f: (a: int32, b: int32) -> int32) {
print(f(b = x, a = y));
}
Implementation
Translation to C is straight forward:
f: (int32, int32) -> int32 = add;
z = f(x, y);
corresponds to
Retcode_T (*f)(int *result, int x, int y) = &add;
(*f)(&z, x, y);
While we are on it, we could also unify syntax:
instead of writing
fn id(x: int32): int32 {
return x;
}
we could write
let id: (x: int32) -> int32 = {
return x;
}
Currently, both of these references of foo
compile to the same code:
fn foo(): int32 {
return 1;
}
fn bar() {
let x1 = foo();
let x2 = foo;
}
If we were a referentially transparent language, this wouldn't interfere: passing a function () -> int32
or a value int32
would be the same (and indeed both would have isomorph types), since all such functions would have to be constant.
However, since our functions have side effects not represented by a type system, calling foo
or passing it as a function reference is different, as are their types.
If we always interpret function names as calls without arguments, we can't formulate references to those functions. Options are:
- Disallow "Supplier"-functions as arguments
- Make every function call explicit
- Introduce special syntax for function references
- Detect whether a referenced function should be a call and when it should be a reference, choose one of the above options for undetectable cases