Functions
LIGO functions are the basic building block of contracts. For example, entrypoints are functions and each smart contract needs a main function that dispatches control to the entrypoints (it is not already the default entrypoint).
The semantics of function calls in LIGO is that of a copy of the arguments but also of the environment. In the case of PascaLIGO, this means that any mutation (assignment) on variables outside the scope of the function will be lost when the function returns, just as the mutations inside the functions will be.
#
Declaring FunctionsThere are two ways in PascaLIGO to define functions: with or without a block.
#
BlocksIn PascaLIGO, blocks enable the sequential composition of instructions into an isolated scope. Each block needs to include at least one instruction.
If we need a placeholder, we use the instruction skip
which leaves
the state unchanged. The rationale for skip
instead of a truly
empty block is that it prevents you from writing an empty block by
mistake.
Blocks are more versatile than simply containing instructions: they can also include declarations of values, like so:
Functions in PascaLIGO are defined using the function
keyword
followed by their name
, parameters
and return
type definitions.
Here is how you define a basic function that computes the sum of two integers:
The function body consists of two parts:
block { <instructions and declarations> }
is the logic of the function;with <value>
is the value returned by the function.
#
Blockless functionsFunctions that can contain all of their logic into a single expression can be defined without the need of a block:
The value of the expression is implicitly returned by the function. Another example is as follows:
You can call the function add
defined above using the LIGO compiler
like this:
#
Anonymous functions (a.k.a. lambdas)It is possible to define functions without assigning them a name. They are useful when you want to pass them as arguments, or assign them to a key in a record or a map.
Here is how to define an anonymous function:
You can check the value of a
defined above using the LIGO compiler
like this:
If the example above seems contrived, here is a more common design pattern for lambdas: to be used as parameters to functions. Consider the use case of having a list of integers and mapping the increment function to all its elements.
Note that
list_map
is deprecated.
You can call the function incr_map
defined above using the LIGO
compiler like so:
#
Nested functions (also known as closures)It's possible to place functions inside other functions. These functions have access to variables in the same scope.
#
Recursive functionLIGO functions are not recursive by default, the user need to indicate that the function is recursive.
At the moment, recursive function are limited to one (possibly tupled) parameter and recursion is limited to tail recursion (i.e the recursive call should be the last expression of the function)
In PascaLIGO recursive functions are defined using the `recursive` keyword