Functions - Manhunter07/MFL GitHub Wiki
Functions are callable entities that allow code to be stored and re-used with an indefinite amount of arguments later. In contrast to constants, they are evaluated on each call and not when they are declared. This means that they may use Identifiers that do not exist at the time of declaration. This means that function calls are therefore slower than constants and variables, because the call stack must be altered and the syntax must be evaluated on every call. Unlike variables, functions cannot be overwritten; attempting to re-declare a function object will cause an exception.
Declaration
Functions are declared with the function
keyword, followed by the function head, an equality sign and the function body. The function head consists of the function name and an optional list of parameters. The function body consists of an expression that is parsed at compile-time and executed at run-time. Constants can be declared locally.
Parameters
Main article: Function parameters
Function parameters are declared after the function name and must be placed between parentheses (those may be omitted if no parameters are to be declared). Each parameter has got an optional name, type and default value. Like arguments, they are separated by a comma.
Parameter groups
Multiple parameters may be howeveer sticked together in order to form a parameter group. Those groups consist of multiple names (or placeholders) and one (optional) unified type constraint and default value. Group members are separated by an ampersand instead of a comma.
The ability to use parameter groups is designed as being purely semantic sugar. The compiler internally resolves them as individual parameters, regardless of whether they are in a group or not.
Parameter operations
Parameters may contain an immediate operation using one of the standard operators like a negation, allowing math equasion-like semantics. This makes possible function declarations like function f(-x) = -f(-x)
. Additionally, each parameter may have absolute bars around it. However, keep in mind that because the compiler cannot perform a dynamic or context-based operation when creating a function, no calls to other functions are possible. If you need to call a function uppon a parameter, you will have to do this manually in the function body.
The default value of a parameter and its type constraint must support the operation. This is not being checked at compile-time, violations will cause an exception at run-time however.
Local helpers
Main article: Function helpers
There are cases when it is handy to use magic objects inside a function rather than to manually declare them or use unnamed constants. Since MFL is a functional language, functions are supposed to build the core focus of the language and shall be as convenient to use as possible. For this case, there are a hand full of pre-declared entities which are exclusively for the use inside such functions. Those are only accessible from inside functions and cannot be used anywhere else (including in other declarations like constants). This includes the Self
constant, the Params
record and the Args
array.
Calling
When a function has been declared, calling a function is done by its identifier, similar as with any other declared object. If one or more argument(s) shall be passed to the call, they can be passed separated by commas within parentheses. If a function does not require arguments for call, parentheses are optional.
Error
Error()
Error("Failed")
Sin(1)
Cos(4 * (Pi + 0.2))
Index("c", "Lorem ipsum dolor sit amet, consetetur sadipscing elitr")
You can explicitely name arguments as well, allowing to leave out non-trailing optional arguments or to change their order. After a named argument there cannot follow any ordered arguments. Named arguments cannot be passed to variable argument parameters.
function Foo(A, B = 5, C) = \...\
Foo(1, 2, 3) \Calls Foo with A=1, B=2, C=3\
Foo(1, C = 6) \Calls Foo with A=1, B=5, C=6\
Foo(C = 6, A = 4) \Calls Foo with A=4, B=5, C=6\
Functions can be called anywhere where dynamic values are allowed. This includes other function bodies, the body of the same function (recursion), parameter fallback values of other functions or initial values of variables for example.