function main($args) //Do some stuff here end function
Functions became a huge part of YASS in version 1.3.4 when they became
importable using the import
function (and later the import
feature). This meant that compiled scripts could be
imported into the current script.
Since version 1.4.1, functions can be given a scope. A scope can be normal, private or public. The previous example showed a function with the normal scope. This is roughly equivalent to private. Private means that the function may not be accessed in any program other than it's own. Public allows other scripts or programs to access the function.
Because of the powerful way in which ZPE handles this, the import command is extremely useful for importing existing, compiled scripts.
The following sample demonstrates three functions, each with a different scope.
function main($args) //This function has the normal scope end function private function main($args) //This function has the private scope end function public function main($args) //This function has the public scope end function
Nested functions
Many languages allow the use of nested functions. Since functions are first-class citizens, they also allow for encapsulation of internal methods. In this case, a function may itself contain a function:
function main($args) function say_name() print("Hello there Jamie") end function say_name() other_function() end function function other_function() //This will throw a ZPE WARNING as it cannot find the say_name function say_name() end function
Further to this, one of the most useful features of ZPE/YASS is that you can actually embed a function declaration within another construct, say an if statement, then promote the function to a global function using the global keyword that was added in ZPE 1.10.12 (previous versions did have the global function, but it was only applicable to variables).
function operation() print("Please insert a value") $x = value(input()) print($x) if($x > 20) global function runnableFunction() print("This function is running") end function end if end function function test() runnableFunction() end function function main() print($x) operation() test() print($x) end function
Lambda functions
As of version 1.3.7.44 lambda (λ) expressions have been supported in ZPE. These are known as anonymous functions and they are designed to make the language more flexible and simpler. They are, without any doubt, my favourite feature of the language and you will see that a lot of my functions benefit from the use of lambda functions.
A lambda function or lambda abstraction is a function that is not bound to any identifier, that is, the function is never defined as a function but it can be assigned to a variable and so on. ZPE version 1.3.7.44 added support for lambda expressions.
The syntax is shown below:
$foo = function($x, $y, $z){return $x + $y + $z} $bar = function($x, $y, $z) return $x + $y + $z end function print($foo(3, 4, 6)) print($bar(3, 4, 6))
The language provides two ways of defining these functions, one is the C-like way of using curly braces ({}) around the function
and the second is to use the end function
keywords to terminate the function.
Functions need not have a return value, that is, no return
function is required in order
for this to work:
$foo = function($x){print ($x + 5)} $foo(3)
Lambda expressions also can be given values straight from the declaration, which can make them more useful in other functions:
$v = 10 print(function($x){return ($x + 5)}($v))
The result of this evaluation is 15, so the print
function will simply print 15. Variables, functions and so on
can all be used as well.
Lambda functions are also very useful with the special csv_decode
function, which takes a function as it's
optional second parameter. Rather than defining some function that may only be
used once and then calling the handle_of
function on that function, it may make more sense to define a lambda function:
$content = "32, 41, 91, 36" $out = csv_decode($content, function($x){return $x + 5}) //Should print 37, 46, 96, 41 print($out) $out = csv_decode($content, function($x, $rowpos, $columnpos){ return $x + 5 + $columnpos }) //Should print 37, 47, 98, 44 because the column position is added to the value print($out)
Also note, that unlike Python, lambda functions can be defined across many lines, not just one.
The previous example could also be rewritten to store a lambda function in a variable an call it using it's variable reference:
$content = "32, 41, 91, 36" $out = csv_decode($content, function($x){return $x + 5}) //Should print 37, 46, 96, 41 print($out) $csv_func = function($x, $rowpos, $columnpos) return $x + 5 + $columnpos end function $out = csv_decode($content, $csv_func) //Should print 37, 47, 98, 44 because the column position is added to the value print($out)
It is important to note that ordering of lambda variables is important. For a function like csv_decode
the order is
crucial but it can be any number of parameters so for instance $columnpos
need not be specified.
Also, parameter names do not matter either since when the csv_decode
function is
run it allocates values to the parameters from left to right, not based on names.
Short-hand lambda functions
Version 1.6.7 introduces an alternative syntax similar to JavaScript that allows anonymous
functions to be defined with the fat arrow (=>
):
$foo = ($x, $y, $z) => {return $x + $y + $z} $bar = ($x, $y, $z) => return $x + $y + $z end function
Return
The return
keyword in YASS is used to provide a value back
to the function call.
function doubleNumber($num) return $num * 2 end function $x = doubleNumber(10) print($x)
Return types
ZPE 1.10.8 added support for return types on functions. This allows for strong typing and takes away from the dynamic typing that functions offered before.
function typedFunction($args) : string return "Hello world!" end function
This function promises to return a string and returns a string, however, the following function will throw an error.
function typedFunction($args) : number return "Hello world!" end function
ZPE 1.11.4 (OmegaY) also supports union return types. This basically means that the return type can be one of many return types. In the example below, a boolean value or a number can be returned.
function linearSearch($items, $term) : boolean | number for ($i = 0 to list_get_length($items)) if($items[$i] == $term) return $i end if end for return false end function $l = [11, 22, 33, 44, 55] print(linearSearch($l, 24)) print(linearSearch($l, 22))
Multiple return values
ZPE 1.12.10 (Scottish Seagul, October 2024) added support for multiple return values using the tuple syntax:
function doubleNumber($num1, $num2, $num3) return $num1 * 2, $num2 * 2, $num3 * 2 end function ($x, $y, $z) = doubleNumber(10, 30, 50) print($x) print($y) print($z)
Parameters
Functions can take a set of parameters, specified within the brackets. When a function is defined, the parameters are called formal parameters. When the function is called they are known as actual parameters.
Optional parameters
Any parameter can be optional, the only thing that must be done after that
is to determine whether it has been set or not. The is_set
predefined function is very useful for this purpose.
In some senses, optional parameters was a side effect of the main development of ZPE. It is useful and remains as an option in all versions.
function test($arg1, $arg2, $arg3) if(is_set($arg2) && is_set($arg3)) print($arg2) print($arg3) end if end function function main () test(10) test(10, 20) test(10, 20, 30) end function
Default values
A default value is somewhat of a fall back if a parameter is not given an argument. This only works with non-named parameters. Default values were officially supported (although added much earlier the implementation wasn't finished) from ZPE version 1.8.9.
function test($arg1, $arg2, $arg3 = 90) print($arg1, $arg2, $arg3) end function function main () test(10, 20) end function
Infinite parameters
ZPE 1.8.11 (North, released in October 2020) added support for infinite parameters. This feature is very powerful and allows programmers to write just one parameter followed by the double dot (..) rather than specifying parameters.
Further to this, infinite parameters are numbered automatically.
function main() infiniteParameters(10, 20, 30) end function function infiniteParameters($i .. ) print($i0) print($i1) print($i2) print($i) end function
In this example, the variable $i
is an infinite
parameter list. Notice that this creates $i0
, $i1
and $i2
as three arguments have been given. The $i
variable will contain a list of all infinite parameters.
A really good example comes from my Standard Library for YASS - a project dedicated to showcasing the features of the YASS language. This next example creates an addAll function (based on the infinite_product_calculator function in the Standard Library) with infinite parameters:
function main() print(addAll(10, 20, 30)) end function function addAll($n ..) $total = 0 $len = list_get_length($n) for($i = 0 to $len) $total = $total + $n[$i] end for return $total end function
Typed parameters
ZPE 1.10.8 added support for providing data types to parameters. It is built upon TYPO v2 and extends the TYPO functionality further. Adding data types to values adds very little performance penalty due to the way TYPO v2 was developed.