Functions and Closures
Functions and closures are both ways of defining sequences of expressions for later use, and/or encapsulating your expressions.
Function Declarations
Functions are declared as a top level statement using @function [identifier](parameter-list) {...}
where in the ...
is a list of function level statements. The parameter list is a ',' separated list of parameters of the form $parameter-name
or $parameter-name:[expression]
where the expression describes the default value for that parameter.
Functions have access to every top level variable declared/imported before the function declaration inside their body, and they have access to every function defined even after their declaration, as long as that definition is reached by the time of the function call.
A few example function declarations are as follows:
Declaring "Member" functions
Sometimes you may want to overload functions depending on the type of the first argument when called like a member function (described below), or you may want the function to only be used with that type when used like a member function, in that case you can define your functions with the name prefixed by the "type" of argument you want the first argument to be, or to overload based on. These types are defined in Values, Variables, and Exceptions, where they are in parentheses in the headers of the different types of Values.
A few example of member functions is as follows
Invoking Functions
To invoke a function in an expression, it is quite simple, you put the function name you want to invoke, then a (
, a comma separated list of expressions for the parameters (parameters can also be named, by doing $parameter-name:expression
), and a )
. This when computed will pass the parameters into the function, and run it, and it will evaluate to the result of the function you wanted to call.
A few examples of this are as follows:
Invoking "Member" Functions
To invoke a "member" function, you do [expression]:[function-name]([arguments])
, which computes the expression, and gets the type of the resulting value for checking which function it needs to call, as first it checks for a function named [type].[function-name]
and if that exists, it will use that function, otherwise it will use the default function named [function-name]
. And once this function is found, it will be invoked, with the leftmost argument being the result of the computation of the expression, and the other arguments passed to the right of that.
A few examples of invoking the previous declared functions as member functions are as follows:
Closure Declarations
A closure is an anonymous function who is a child of the environment that it is in (i.e.) it has access to all the variables in the environment it was declared in that were declared before its declaration. They are declared much like functions, but instead have no names, and are not at the top level, but rather values inside of expressions.
A few examples of closure declarations are as follows:
Invoking Closures
To invoke closures you must have the builtin:functional
library imported, which defines a member function called closure.invoke
, which when called with a closure and the closures arguments (named or positional are allowed), invokes the closure with the list of arguments passed, and returns the result.
Examples of this, invoking the previously defined closures above are as follows:
Function/Closure Level Statements
Functions and closures have different statements allowed within them than that of selection blocks and the top level.
Variable Declarations
Variable declarations are the same as every other place they can be declared, $variable-name: [expression]
.
For an example of variable declarations within a function:
Conditionals
Conditionals follow the same @if
, @else-if
, @else
structure as in other selection blocks and top level statements.
For an example of conditionals within a function:
Returning Values
Returning the results of functions to the invoker is quite simple, you just do @return [expression];
.
For example, the following function always returns 5 when called.
For Loops
For loops allow you to repeat a block of function statements over a range of numbers, they are of the form @for $value from [start] through/to [end] {...}
where the ...
is the block of function statements. The difference between through
and to
, is that through
includes the endpoint, and to
does not. The loop then iterates $value
over every from the start to whatever end value it has.
For examples of usages of for loops:
Each Loops
"Each" loops are used to iterate over collections/sequences (strings/lists/maps), there are 2 forms for them:
@each $value in $collection {...}
@each $key, $value in $collection {...}
In both forms, the ...
is the list of function statements you want to do for each item in the collection, the difference is the second one gives you both the key, and value for each item in the collection, in the case of strings and lists this is the index starting from 0, otherwise, it is the key for the object in the map.
A few example of each loops are as follows:
While Loops
While loops are loops that repeat a sequence of function statements while a condition remains true, they are of the form @while [condition] {...}
where ...
is the sequence of function statements you wish to repeat while [condition]
evaluates to true.
An example of a while loop is as follows: