Implement typed function references
Currently, function references are not safe. If you pass a function reference which, for example, receives a STRING as argument, as an argument for a definition, which then calls funcReference(1), there will be no error at the start of the definition; in fact, it will only occur when executor tries to call the function, which then FunctionCall::resolve will throw an InvalidFunctionParameterException.
Since normal function calls (without references) are safe (it is: argument type validation are done before trying to call it), then this overhead of validation in FunctionCall::resolve is only because of function references being untyped.
Definition:
... def someFunction(ref**<string, int>** callback) { ...
Things to note:
- There will be 2 new token types
- The parser will need to read the value types at parseDefinition()
- The actual validation of argument types will be done when passing the ReferenceValue as argument for the Definition. Probably it will be inside Definition::call.
- VarArgs function should be always valid, no matter which types are in the reference declaration.
Example usage:
Please note that std::println is a varargs function. Therefore, the fourth note applies here.
The examples below must work:
def send(ref<string> callback) {
callback("João")
}
send(@println)
def send(ref<any> callback) {
callback(1)
}
send(@println)
def send(ref<int, any> callback) {
callback("João")
}
send(@println)
The examples below must not work:
def send(ref<int> callback) {
callback(1)
}
send(@browse)
def send(ref<string, any> callback) {
callback("João", 1)
}
send(@browse)