
無為的程式設計
|
213
雖然的確發生了某些事情,但是我們完全沒有得到想要的結果:最後的運算式是
-> p {
-> x { p[-> p { -> x { p[x] } }[p][x]] } }
,但是數值 2 的 lambda 演算表示應該是
->
p { -> x{ p[p[x]] } })]
。哪裡出錯了?
不一致是因為我們使用的估算策略所造成。結果裡仍然埋著可以簡化的函式呼叫(例如
可以將呼叫
-> p { -> x { p[x] } }[p] 簡化成 -> x { p[x] }
),但是
#reduce
不會處理這
些,因為它們出現在函式主體裡,而我們的語意不會將函式視為可以簡化
9
。
但就如同第 170 頁的『相等』所討論,如果它們的行為相同,仍然可以將兩個語法不
同的運算式視為相等。我們知道數值 2 的 lambda 演算如何表現:如果我們給它兩個引
數,它會在第 2 個引數呼叫第 1 個引數兩次。所以讓我們試著以兩個虛構的變數 inc 和
zero
10
呼叫我們的運算式,並且看看它實際完成了什麼:
>> inc, zero = LCVariable.new(:inc), LCVariable.new(:zero)
=> [inc, zero]
>> expression = LCCall.new(LCCall.new(expression, inc), zero)
=> -> p { -> x { p[-> p { -> x { p[x] } }[p][x]] } }[inc][zero]
>> ...