学习交流编程语言理论的平台?


#41

就是元循环求值器,你可以参考:http://www.yinwang.org/blog-cn/2012/08/01/interpreter

喔,原来你卡在这里啊。

nameless representation of terms 对初学者确实比较麻烦,主要是实现细节比较多(我记得SICP里也有讲到过它,虽然不是用在同一个地方。。。)

注:nameless representation of terms本质上只是一种优化策略,它并不是这本书的核心(实际上,你使用改名的方法也可以实现同样的目的),建议不要过多的浪费时间在上面。


#42

这个挺有意思,我可以用Emacs Lisp实现一个。

好滴。


#43

没用过 OCaml 是没法理解为什么有些地方要这么设计的。更何况这书是用 OCaml 写 OCaml,不像 Scheme 写 Scheme 顶破天也就那么复杂,要求事先熟悉 OCaml 是很合理的

我觉得能写几道 Project Euler 已经是很低的要求了。再低就是要求写 hello world 了。以 Helium 教学编译器提供的没有 typeclass 的 Haskell98 而论完全掌握真的是很简单了,不比 R6RS 复杂多少。

那刷完我给的那个合集就有同等水平。


#44

我觉得吧,至少写个R5RS的解释器不需要懂这么多东西,会C,看完SICP和TSPL就行。


#45

你说的对 会了C语言 再看懂数据结构与算法 你就能做很多事情了


#46

这个比TAPL简单多了。我的实现跟他的应该差不多。

(require 'pcase)
(require 'cl-lib)

(defun calc (exp)
  (pcase exp
    (`(,op ,e1 ,e2)
     (let ((r1 (calc e1))
           (r2 (calc e2)))
       (pcase op
         ('+ (+ r1 r2))
         ('- (- r1 r2))
         ('* (* r1 r2))
         ('/ (/ r1 r2)))))
    ((pred numberp) exp)))

(defun ext-env (bind env)
  (cons bind env))

(defun ext-envs (bind-list env)
  (append bind-list env))

(defun lookup (var env)
  (cl-loop for bind in env
           for vr = (car bind)
           for va = (cdr bind)
           if (eq var vr)
           return va
           finally return nil))

;; (closure f env)
;; (lambda (x) body)
;; (let (var val) body)
;; (function arg)

(defun interp (exp env)
  (pcase exp
    ;; variable
    ((pred (lambda (e) (and (symbolp e) (not (booleanp e)))))
     (interp (lookup exp env) env))
    ;; single lambda / closure
    (`(lambda . ,_) `(closure ,exp ,env))
    (`(closure . ,_) exp)
    ;; lambda / closure application
    (`((lambda . ,rest) ,arg)
     (interp (list (interp `(lambda . ,rest) env) (interp arg env)) env))
    (`((closure (lambda (,x) ,body) ,e) ,arg)
     (interp body (ext-env (cons x (interp arg (ext-envs e env)))
                           (ext-envs e env))))
    ;; symbol application
    (`(,f ,a) (when (and (symbolp f) (not (booleanp f)))
                (interp `(,(interp f env) ,(interp a env)) env)))
    ;; let
    (`(let (,var ,val) ,body)
     (interp body (ext-env (cons var (interp val env)) env)))
    ;; arithmetic
    ;; op e1 e2 can be confused with let bind body
    (`(+ ,e1 ,e2) (+ (interp e1 env) (interp e2 env)))
    (`(- ,e1 ,e2) (- (interp e1 env) (interp e2 env)))
    (`(* ,e1 ,e2) (* (interp e1 env) (interp e2 env)))
    (`(/ ,e1 ,e2) (/ (interp e1 env) (interp e2 env)))
    ;; number
    ((pred numberp) exp)))
(interp '(let (x (lambda (x) (x 1)))
           (x (lambda (x) (+ 1 x))))
        nil)
;;=> 2

(学Haskell去了


#47

我觉得macro玩得熟练的话,和写解释器是差不多的


#48

其实这本书把所有关于实现的章节都跳过也没什么问题吧。Chapter dependencies 那张图里把4,6,7,10,17,25 都扣掉以后还是 self-contained。(当然这么说有点不负责任,毕竟我只看过几章。)


#49

macro (expender) 和 interpreter 差别还是挺大的吧


#50

对于lisp系,我个人感觉是一样的


#51

Ok,我试试