Scheme 方案:+;这不是一个程序吗?

Scheme 方案:+;这不是一个程序吗?,scheme,r5rs,Scheme,R5rs,我试图学习scheme(更具体地说是R5RS),我想定义一个过程,该过程将一个包含3个元素的列表作为输入,例如:'(5+2), 其中中间参数始终是运算符,第一个和第三个始终是操作数 示例: (proc-mid '(1 + 2)) --> 3 (proc-mid '(1 list 2)) --> (1 2) (proc-mid '(20 * 5)) --> 100 到目前为止,我的代码是: (define (proc-mid exp) (define proc (cad

我试图学习scheme(更具体地说是R5RS),我想定义一个过程,该过程将一个包含3个元素的列表作为输入,例如:'(5+2), 其中中间参数始终是运算符,第一个和第三个始终是操作数

示例:

(proc-mid '(1 + 2))
--> 3
(proc-mid '(1 list 2))
--> (1 2)
(proc-mid '(20 * 5))
--> 100
到目前为止,我的代码是:

(define (proc-mid exp)
    (define proc (cadr exp))
    (proc (car exp) cddr exp))
然而,我得到一个错误,说:

    application: not a procedure;
     expected a procedure that can be applied to arguments
      given: +
      arguments...:

那么,我的问题是,为什么不将+作为一个过程进行评估?

在您的情况下,
+
是一个原因

将文本(非数字/布尔值等)转换为符号

(define l1 '(1 a #f +))

(symbol? (car l1))
(symbol? (cadr l1))
(symbol? (caddr l1))
(symbol? (cadddr l1))
#f

#t

#f

#t

您可以使用
eval
仔细评估文本,如下所示:


文档:

在您的案例中,
+
是一个原因

将文本(非数字/布尔值等)转换为符号

(define l1 '(1 a #f +))

(symbol? (car l1))
(symbol? (cadr l1))
(symbol? (caddr l1))
(symbol? (cadddr l1))
#f

#t

#f

#t

您可以使用
eval
仔细评估文本,如下所示:


文档:

当Scheme计算
(+ab)
时,它计算操作数
+
,希望它有一个过程值,然后
a和
b可能都应该计算为数值。然后
apply
+
的结果与操作数的结果一起应用

引用的表达式
”(+ab)
不计算其参数。因此,
+
不会计算为过程,
a
b
不会计算为数字。该值就是列表
(+ab)
。如果您使用
列表
进行此操作,您将执行
(列表'+'a'b)
。如果你做了
(列表+ab)
,你会得到3个变量的评估值,并得到类似
(#23)
的结果

带引号的表达式
'(+23)
是特殊的,因为您有数字文字并且它们是自计算的,但是
+
仍然是一个符号,而不是看起来相同的计算变量,因为quote不计算它的参数

(应用“+”(2 3))
不起作用,因为
+
不是在一个过程中

您也许应该将原语映射到实际的过程

;; assoc between symbols and their corresponding procedure value
(define PROCS `((+ . ,+) (* . ,*)))

(define (get-proc symbol)
  (let ((match (assq symbol PROCS)))
    (if match
        (cdr match)
        symbol)))

当Scheme计算
(+ab)
时,它计算操作数
+
,希望它有一个过程值,然后计算
a
b
,这两个值可能都应该计算为数值。然后
apply
+
的结果与操作数的结果一起应用

引用的表达式
”(+ab)
不计算其参数。因此,
+
不会计算为过程,
a
b
不会计算为数字。该值就是列表
(+ab)
。如果您使用
列表
进行此操作,您将执行
(列表'+'a'b)
。如果你做了
(列表+ab)
,你会得到3个变量的评估值,并得到类似
(#23)
的结果

带引号的表达式
'(+23)
是特殊的,因为您有数字文字并且它们是自计算的,但是
+
仍然是一个符号,而不是看起来相同的计算变量,因为quote不计算它的参数

(应用“+”(2 3))
不起作用,因为
+
不是在一个过程中

您也许应该将原语映射到实际的过程

;; assoc between symbols and their corresponding procedure value
(define PROCS `((+ . ,+) (* . ,*)))

(define (get-proc symbol)
  (let ((match (assq symbol PROCS)))
    (if match
        (cdr match)
        symbol)))

+
在大多数范围内都绑定到一个过程,但它本身是一个符号。它几乎总是绑定到的过程是一个过程。 例如,在
(let((+“+”)+)
+
是一个字符串。在任何合理的状态下,你都会有

(过程?'+)
=>#f
(程序?+)
=>#t
, 所有这些都是说,在大多数编程语言中,您可以将可用变量/函数等的环境想象为一个符号到值的字典,只是在scheme中,指向值的符号可以作为值访问。因此,在引用列表
(+12)
时,您引用的是符号列表,即环境/字典中的键,而不是值。
(符号?(cadr'(1+2))

(过程?(cadr(列表1+2))

+
在大多数范围内都绑定到过程,但其本身是一个符号。它几乎总是绑定到的过程是一个过程。 例如,在
(let((+“+”)+)
+
是一个字符串。在任何合理的状态下,你都会有

(过程?'+)
=>#f
(程序?+)
=>#t
, 所有这些都是说,在大多数编程语言中,您可以将可用变量/函数等的环境想象为一个符号到值的字典,只是在scheme中,指向值的符号可以作为值访问。因此,在引用列表
(+12)
时,您引用的是符号列表,即环境/字典中的键,而不是值。
(符号?(cadr'(1+2))
(程序?(cadr(列表1+2)))