Erg subroutines have a feature called a "closure" that captures external variables.
outer = 1 f x = outer + x assert f(1) == 2
As with immutable objects, mutable objects can also be captured.
sum = !0 for! 1..10, i => sum.add!i assert sum == 45 p!x= sum.add!x p!(1) assert sum == 46
Note, however, that functions cannot capture mutable objects. If a mutable object can be referenced in a function, you can write code like the following.
# !!! This code actually gives an error !!! i = !0 f x = i + x assert f 1 == 1 i.add! 1 assert f 1 == 2
The function should return the same value for the same arguments, but the assumption is broken.
i is evaluated only at call time.
.clone if you want the contents of the mutable object at the time the function was defined.
i = !0 immut_i = i.clone().freeze() fx = immut_i + x assert f 1 == 1 i.add! 1 assert f 1 == 1
avoid mutable state, functional programming
# Erg sum = !0 for! 1..10, i => sum.add!i assert sum == 45
The equivalent program above can be written in Python as follows:
# Python sum = 0 for i in range(1, 10): sum += i assert sum == 45
However, Erg recommends a simpler notation. Instead of carrying around state using subroutines and mutable objects, use a style of localizing state using functions. This is called functional programming.
# Functional style sum = (1..10).sum() assert sum == 45
The code above gives exactly the same result as before, but you can see that this one is much simpler.
fold function can be used to do more than sum.
fold is an iterator method that executes the argument
f for each iteration.
The initial value of the counter that accumulates results is specified in
init and accumulated in
# start with 0, result will sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45
Erg is designed to be a natural succinct description of programming with immutable objects.