It should be possible to take Roto functions and store them into variables. For example:
fn twice(x: u32) -> u32 {
2 * x
}
fn thrice(x: u32) -> u32 {
3 * x
}
fn main(select: bool, x: u32) -> u32 {
let f = if select {
twice
} else {
thrice
};
f(x)
}
There are some limitations:
- Function types only unify if they have the same parameters and return type
- Methods cannot be stored in function pointers, unless they are referenced via the type (which is currently not possible).
- There is no closure or even anonymous function syntax yet.
This should be relatively easy within Roto, but passing function pointers in and out of Roto is probably quite difficult.
It is also work towards Query DSL or API · Issue #98 · NLnetLabs/roto · GitHub .
Extension 1: Nested functions
Once we have this, it might make more sense to declare functions in other functions:
fn main(x: i32) -> i32 {
fn plus_one(x: i32) -> i32 {
x + 1
}
plus_one(x)
}
Extension 2: Anonymous functions
Once we can use functions in more places, it makes sense to provide some syntax for anonymous functions:
fn main(x: i32) -> i32 {
let plus_one = fn(x: i32) { x + 1 };
plus_one(x)
}
Extension 3: Closures
Finally, we might want to extend anonymous functions (when they have been implemented) so that they can capture variables from their environment.
fn main(x: i32) -> i32 {
let plus_one = fn() { x + 1 };
plus_one(x)
}