Re: [問題] letrec 為何可以成立? (In scheme, ma …
我發現我沒頭沒腦的沒說清楚環境就直接發問了....
昨天適逢debug整夜後的腦袋混沌狀態...^^"
不過謝謝大家的回答,我有點頭緒知道自己卡住的地方了....
在發問前我先看了這篇在LtU 論壇的發問
http://lambda-the-ultimate.org/node/2971
標題是: doing letrec with lambdas
課程上正在用scheme實作一個interpreter(mini-scheme),有environment機制
概念上是先訂一組global environment
另外這個interpreter也支援high order function.
在這interpreter裡面,lambda function evaluation的實作是:
(eval (lambda ( arguments ) (function body) ) env )
會被轉為
(%func ( arguments ) ( function body ) env )
因為lambda function 有打包當時環境,所以後來執行該lambda function
時, function body 會查找的便是打包的環境 (所以是static scoping?)
題目是要在這樣的環境下實作 define, let, let*, letrec 這幾個機制
其共通性就是在處理這些function call 的時候
要如何對應的更改其中的environment.
我想發問的是在這種語言條件的情境下,letrec的概念大概是如何?
例如 define 其實就是把global 環境多加一組binding
let 就是先把 let 的東西一口氣加入環境後,在用更改過的環境eval body
可是letrec 的問題如下段程式碼描述:
(letrec ( (f (lambda (x) ...有遞迴的call 到f... ) ) ) ( f 3 ) )
f 是個遞迴函式,call到自己 body則是使用f
當我試圖要在環境中先製造一組 (f (%func ... env ) ) 的bindings 時
f 要bind 到一個lambda function 的值~其中會包一個env
而因為這個lambda function 裡面會使用到 f,
所以包進去的env 裡面也會需要有 f bind 一個lambda function 的值
可是這個 lambda function 也需要有個env .... (以下省略,總之無限後退)
我後來的實作方法是先在目前的environment造一組 ( f 'dontcare ) 的binding
用這個environment eval 此lambda function 後 ,此時回傳一個 (%func ... ) 的值
再利用set-cdr! 把本來設為 'dontcare 的binding 改為回傳的那個值
這樣的確就成功實作letrec了,可是我卻不之所以然....
所以想問問有沒有比較學理的描述可以說明我這樣的行為。
文章一開始提到的那個發問裡面
有提到說如果語言機制裡面允許 "mutable references" 就可以做到我正在做的事情
可是我想這也只是工具上的不同
我會再去弄那本課本來看~先謝過大家的回答了!
--
愛與被愛....都是很毒很毒的毒藥
愛著一個人....只會感受到付出沒有回報的悲傷
被一個人愛上....卻會因為不能回應而覺得有罪惡感
也許...愛..和被愛..都只有一種解藥....那就是....
深深愛上一個深愛你的人
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.45.217.232
討論串 (同標題文章)
以下文章回應了本文:
完整討論串 (本文為第 3 之 6 篇):
PLT 近期熱門文章
PTT數位生活區 即時熱門文章