FOLD<N> macro makes it possible to implement operations on a list of values such as sum, filter, map, zip, exists, etc. The macro behaves like the fold or reduce function in other programming languages.
FOLD<N>(list, start, foldFunc)
| Parameter | Description |
|---|---|
| N | Maximum number of iterations, up to 1000. |
| list | List of values. |
| start | Initial value. |
| foldFunc | Combining function. |
The combining function accepts two input parameters: the intermediate result and the next element of the list. Macro FOLD<N>(list, start, foldFunc) means:
The value of N must be known in advance. If there are more elements in the list than specified in FOLD, the script fails. The complexity of FOLD<N> corresponds to the complexity of foldFunc multiplied by N plus extras. The FOLD<N> macro is a syntactic sugar; it is unwrapped by the compiler. Therefore, in particular, the size of the script increases linearly with N.
func sum(accum: Int, next: Int) = accum + next let arr = [1,2,3,4,5] FOLD<5>(arr, 0, sum) # Result: 15
The expression
FOLD<5>(arr, 0, sum)
after compiling and decompiling will look like this:
let $list = arr
let $size = size($list)
let $acc0 = 0
if (($size == 0))
then $acc0
else {
let $acc1 = sum($acc0, $list[0])
if (($size == 1))
then $acc1
else {
let $acc2 = sum($acc1, $list[1])
if (($size == 2))
then $acc2
else {
let $acc3 = sum($acc2, $list[2])
if (($size == 3))
then $acc3
else {
let $acc4 = sum($acc3, $list[3])
if (($size == 4))
then $acc4
else {
let $acc5 = sum($acc4, $list[4])
if (($size == 5))
then $acc5
else {
let $acc6 = sum($acc5, $list[5])
throw("List size exceed 5")
}
}
}
}
}
}func mult(accum: Int, next: Int) = accum * next let arr = [1,2,3,4,5] FOLD<5>(arr, 1, mult) # Result: 1204]
The following code composes an array consisting only of even elements of the original array:
func filterEven(accum: List[Int], next: Int) = if (next % 2 == 0) then accum :+ next else accum let arr = [1,2,3,4,5] FOLD<5>(arr, [], filterEven) # Result: [2, 4]
The following code inverts the array, reducing each element by 1:
func map(accum: List[Int], next: Int) = (next - 1) :: accum let arr = [1, 2, 3, 4, 5] FOLD<5>(arr, [], map) # Result: [4, 3, 2, 1, 0]
Elsewhere on this site