iT邦幫忙

0

SICP lec7a : 循環求值器 (Evaluator)

此篇為 SICP教程 7a 的筆記

目前為止,我們一直把程式當成是對機器的描述,如下圖,一個降冪的相乘數列(n!)
https://ithelp.ithome.com.tw/upload/images/20190601/20117516PYkBKm6WYW.png

  • 如果 n 為 0,就把最後面的開關掰到1然後輸出
    https://ithelp.ithome.com.tw/upload/images/20190601/20117516ulcqBlYMKR.png
  • 否則就計算 (* n (fact (- n 1))),先計算(fact (- n 1))
    https://ithelp.ithome.com.tw/upload/images/20190601/20117516ao4je1Yrw3.png
  • 再與n相乘(乘法元件),因為輸出成為n!

Eval is a "Universal Machine"

另一個重要的觀念就是,一台稱為 "Eval" 的機器,它接收上述降冪數列機器的線路圖,就能夠模擬出降冪數列機器的功能。
https://ithelp.ithome.com.tw/upload/images/20190601/20117516vUbhkUQEdx.png
接下來就要實現一個 Eval 機器!
對應程式碼與預期的輸入輸出
程式碼部分:

defn eval
    [exp env]
    (cond
        (number? exp) exp
        (symbol? exp) (lookup exp env)
        (equal? (car exp) 'quote) => (cadr exp) 
        (equal? (car exp) 'lambda) => (list clojure (cdr exp) env) 
        (equal? (car exp) 'cond) => (evcond (cdr exp) env)
        ;; 以上為specail forms
        :else (apply (eval (car exp) env) (evlist (cdr exp) env)) ;先從env中得到procedure + 也從環境中得到 x,最後apply
         
        ;; 若要有效率的判斷,必須將程式碼寫成數據導向 data direct 的,這樣就不會是一系列的cond,會針對bit來做分配。(這部分自己不太清楚)
    )
3 => 3
x => 3; car => #[procedure]
`foo => (quote foo)
(fn (+ x y)) => (Closure (+ x y) env)
(cond (pred1 exec1) (pred2 exec2) ....) => 當pred為true,執行exec
;; 以上為specail forms
(+ x 3)
  • 上述其實就是根據exp表達式的type來進行不同操作,default為組合式
  • 當然還可以繼續加specail forms上去,但加太多會讓語言變得複雜,越是通用的語言,核心要越簡單
  • 以上還有些未定義的東西: apply, lookup, evcond, evlist,下章繼續定義

尚未有邦友留言

立即登入留言