使用纯scheme过程定义一个原语apply

使用纯scheme过程定义一个原语apply,scheme,sicp,Scheme,Sicp,在SICP的章节中 cons仅以程序表示: (define (cons x y) (define (dispatch m) (cond ((eq? m 'car) x) ((eq? m 'cdr) y) (else (error "Undefined operation: CONS" m)))) dispatch) 在中,原语eval与cons (define (eval exp env) (cond

在SICP的章节中

cons
仅以程序表示:

(define (cons x y)
  (define (dispatch m)
    (cond ((eq? m 'car) x)
          ((eq? m 'cdr) y)
          (else (error "Undefined
                 operation: CONS" m))))
  dispatch)
在中,原语
eval
cons

(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
        ((variable? exp) (lookup-variable-value exp env))
        ((quoted? exp) (text-of-quotation exp))
        ((assignment? exp) (eval-assignment exp env))
        ((definition? exp) (eval-definition exp env))
        ((if? exp) (eval-if exp env))
        ((lambda? exp)
         (make-procedure (lambda-parameters exp)
                         (lambda-body exp)
                         env))
        ((begin? exp) 
         (eval-sequence (begin-actions exp) env))
        ((cond? exp) (eval (cond->if exp) env))
        ((application? exp)
         (apply (eval (operator exp) env)
                (list-of-values (operands exp) env)))
        (else
         (error "Unknown expression type -- EVAL" exp))))
然而,这本书并没有试图定义一个原语apply,而是将内置apply包装为

相反,我们假设通过执行以下操作保存了对底层apply的引用
(在基础方案应用中定义应用)

4.1元语言抽象
中,插图将
应用
以及内置的
cons
汽车
cdr
视为理所当然


如何定义原语
应用

您不需要定义
原语应用
。这来自于用于实现evaluator的语言

如果您使用元循环计算器,
原语apply
进入您使用的scheme系统(例如,mit scheme、guile等为您提供
apply
)。如果您使用scheme之外的其他语言(如C)实现一种语言,
原语apply
是用C编写的

例如,如果在目标语言中添加2个数字,要使用C中的
+
运算符来计算结果,
原语apply
首先需要将目标语言的数字表示形式转换为类似C的表示形式,然后再应用原语
+
(来自C)并将结果转换回目标语言。此结果将由
原语apply
以目标语言返回

其思想是,用C语言实现的语言将知道目标语言中对象的表示形式,并且能够将该表示形式转换为C代码可以识别的类似表示形式(尝试查看在某些实现中如何实现大数字,以及在使用lib的实现中添加两个大数字时内部会发生什么情况)。例如,请参阅如何在emacs lisp中实现大数字,在emacs/gnu中计算
(+ab)
时会发生什么情况

您只需要在目标语言中定义要实现的
apply
函数


另一方面,我不理解您为什么将问题与列表构造函数的不同实现结合起来。

您不需要定义
原语apply
。这来自于您用于实现计算器的语言

如果您使用元循环计算器,
原语apply
位于您使用的scheme系统内部(例如,mit scheme、guile等为您提供了一个
应用
)。如果您使用scheme以外的其他语言实现一种语言,如C,则
原语apply
用C编写

例如,如果在目标语言中添加2个数字,要使用C中的
+
运算符来计算结果,
原语apply
首先需要将目标语言的数字表示形式转换为类似C的表示形式,然后再应用原语
+
(来自C)和将结果转换回目标语言。此结果将由
原语apply以目标语言返回

其思想是,用C语言实现的语言将知道目标语言中对象的表示形式,并且能够将该表示形式转换为C代码可以识别的类似表示形式(尝试查看在某些实现中如何实现大数字,以及在使用lib的实现中添加两个大数字时内部会发生什么情况)。例如,请参阅如何在emacs lisp中实现大数字,在emacs/gnu中计算
(+ab)
时会发生什么情况

您只需要在目标语言中定义要实现的
apply
函数


另一方面,我不理解您为什么将问题与列表构造函数的不同实现结合起来。

apply
对于用户定义的过程在第4章中进行了定义。
apply
对于基元函数是检查(基元)名称的条件函数,然后为每个函数选择适当的操作:它执行
cons
cdr
,等等。因此,编写它时,应该知道基本函数,并知道如何管理对每个函数的求值。使用内置应用程序的唯一原因是,解释语言可以像其他程序一样重用其他内置过程原语。如果不允许使用此类原语,但只允许在解释器中定义的过程,则不需要它。
apply
对于用户定义的过程在第4章中定义。
apply
对于原语函数是检查(原语)名称的条件函数,然后为每个函数选择适当的操作:它执行
cons
cdr
,等等。因此,编写它时,应该知道基本函数,并知道如何管理对每个函数的求值。使用内置应用程序的唯一原因是,解释语言可以像其他程序一样重用其他内置过程原语。如果您不允许使用此类原语,但只允许解释器中定义的过程,则不需要它。因为我没有看到将
apply
proc应用于参数的基本情况,对于eval,许多基本情况如'number?return expr;string?return expr,等等“而且所有的基本情况都不会在其中封装另一个评估。@微积分我认为你应该使用SICP的思想编写你自己的代码,因为当你自己尝试时,你会发现这些问题的答案。有很多隐藏的小问题,你只看SICP是看不到的。我明白了,这是一种分派