閉包
Erg子例程有一個稱為"閉包"的功能,可以捕獲外部變量
outer = 1
f x = outer + x
assert f(1) == 2
與不可變對象一樣,可變對象也可以被捕獲
sum = !0
for! 1..10, i =>
sum.add!i
assert sum == 45
p!x=
sum.add!x
p!(1)
assert sum == 46
但是請注意,函數不能捕獲可變對象 如果可以在函數中引用可變對象,則可以編寫如下代碼
# !!! 這段代碼實際上給出了一個錯誤!!!
i = !0
f x = i + x
assert f 1 == 1
i.add! 1
assert f 1 == 2
該函數應該為相同的參數返回相同的值,但假設被打破了
請注意,i
僅在調用時進行評估
如果您想在定義函數時獲取可變對象的內容,請調用.clone
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
上面的等效程序可以用Python編寫如下:
# Python
sum = 0
for i in range(1, 10):
sum += i
assert sum == 45
但是,Erg 建議使用更簡單的表示法 與其使用子例程和可變對象來傳遞狀態,不如使用一種使用函數來定位狀態的風格。這稱為函數式編程
# 功能風格
sum = (1..10).sum()
assert sum == 45
上面的代碼給出了與之前完全相同的結果,但是您可以看到這個代碼要簡單得多
fold
函數可以用來做比sum更多的事情
fold
是一個迭代器方法,它為每次迭代執行參數f
累加結果的計數器的初始值在init
中指定,并在acc
中累加
# 從0開始,結果會
sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i)
assert sum == 45
Erg被設計為對使用不可變對象進行編程的自然簡潔描述