如下面的例子,cons, print可以eval,但是if, define不可以,也不可以apply, 這說明if, define, lambda等關鍵詞不是procedure? 那它們的類型是什麼?怎麼實現(implement)這些關鍵詞的?(PS. 我在寫的micro-scheme解釋器是把所有關鍵詞都當做procedure來處理的。。。。)

Welcome to Racket v5.3.6.&> cons

#&

&> print#&

&> if

stdin::11: if: bad syntax

in: if context...: /usr/share/racket/collects/racket/private/misc.rkt:87:7&> define

stdin::14: define: bad syntax

in: define context...: /usr/share/racket/collects/racket/private/kw.rkt:802:2 /usr/share/racket/collects/racket/private/misc.rkt:87:7


這些是 Special Form 。。。是在解釋器 / 編譯器裏實現的。。。
我記得sicp裡面有講, 典型的就是if, 如果第一個條件為真則後面不會eval, 而scheme裡面的函數在帶入的時候會eval所有的參數, sicp裡面還專門有一個例子, 如果用函數實現if,在遞歸的時候會無法跳出。

你可以將cons 定義成函數,比如

(define cons (lambda (x y) (lambda (f) ( f x y) )))

(define car (lambda (f) ( f (lambda (x y ) (x) ))))
(define cdr (lambda (f) ( f (lambda (x y ) (y) ))))

但是if lambda define 不能


把if當procedure也不是不可以,在解釋器內部把參數包成一個thunk,實現lazy語義就好了
用C實現過一個簡陋的schemeif lambda define這些是symbol讀入pair後,判斷這些關鍵字,會在eval裏執行相應的case
  • Gorden Plotkin, Call-by-name, call-by-value and the λ-calculus
  • Daniel P. Friedman, CONS should not evaluate its arguments


宏呀。要是是procedure的話,scheme不是熱求值的嘛,那你還怎麼把if,quote當作procedure來實現?
你實現一個Scheme的解釋器就都能理解了(逃
推薦閱讀:
相關文章