是否有可能重新实施"申请"在Scheme?

时间:2014-10-24 20:23:57

标签: scheme interpreter apply

如果我遇到原始程序,我是否总是使用基础方案申请?

假设我这样做,我将如何重新实施申请方案解释器来解释自己?

(define apply-1 

  (lambda (proc args)

    (cond ((primitive? proc)
           (apply proc args)) <-- How would I reimplement this
           ((eq? (car proc) 'closure)
            (eval (cadr (cadr proc)) 
                  (bind (car (cdr proc)) args (caddr proc))))  
           (else error))))

1 个答案:

答案 0 :(得分:1)

Primitive-apply是解释器中的原语如何与底层实现实现之间的粘合剂。使用主机apply来应用基本系统中确实是过程的原语是一种技巧。您无法创建主机apply,但您可以使用interpreter原语 - 以不同的方式应用,或者支持其他方式来封装基元。例如

;; define representations for primitives
(define prim-cons (list 'cons)) ; system unique
(define prim-car  (list 'car))
...

;; define primitive? 
(define (primitive? proc)
  (or (eq? proc prim-cons)
      (eq? proc prim-car)
      ...))

;; define primitive apply
(define (primitive-apply proc args)
  (cond ((eq? proc prim-cons) args)
        ((eq? proc prim-car) (caar args))
        ...))

;; boot environment
(define primitive-environment
  (list (cons #t    prim-true)
        (cons #f    prim-false)
        (cons '()   prim-null)
        (cons 'cons prim-cons)
        (cond 'car  prim-car)
        ...))

事实是使用apply只是一种简化,因为实际的原始过程是已解析的对象。它并不总是那样。想象一下,我们尝试优化它:

;; define representations for primitives
(define prim-cons (list 'cons)) ; system unique
(define prim-car  (list 'car))

;; make a list of primitives and their implementation
(define primitives
  (list (cons prim-cons values)
        (cons prim-car  caar)))

;; define primitive? 
(define (primitive? proc)
  (assq proc primitives))

;; make apply-primitive
(define (apply-primitive proc args)
  ((cdr (primitive? proc)) args))

仍有很多样板..为什么不将整个原始列表移动到环境中。

;; make tags
(define *primitive* (list 'primitive))
(define *constant* (list 'constant))

;; make a list of primitives and their implementation
(define boot-env
  (list (list* 'cons *primitive* values)
        (list* 'cons *primitive* caar)
        ...
        (list* #f *constant* #f)
        (list* #t *constant* #t)))

;; verify type
(define (is-type? x type)
  (and (pair? proc)
       (eq? (car proc) type)))

;; define primitive? 
(define (primitive? proc)
  (is-type proc *primitive*))

(define (constant? x)
  (is-type x *constant*))

;; make apply-primitive
(define (apply-primitive proc args)
  ((cdr proc) args))

现在。对于复合程序,我们只有类似的标签。 eval本身变得非常小,因为您甚至可以在您的环境中使用*special-form*来执行类似的操作,使您的eval仅在您评估的值类型之间进行案例分析,而不是特殊情况。

我对apply的一个想法是,当我从解释器调用过程apply时,我希望我的apply成为被调用者。您可以使用apply,但apply实际上也需要由apply处理。当你尝试申请eval时,你会遇到同样奇怪的事情。