方案:+不是程序?

时间:2018-03-07 13:00:44

标签: scheme r5rs

我试图学习计划(更具体地说是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...:

我的问题是,为什么+不被评估为程序?

3 个答案:

答案 0 :(得分:1)

在您的情况下,+symbol,因为

'(element1 element2 ... elementn)

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

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

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

#f的

     

#T

     

#f的

     

#T

您可以谨慎使用eval来评估此answer

中的文字

docs:racket quote

答案 1 :(得分:1)

当Scheme评估(+ a b)时,它会评估操作数+,并且希望它有一个过程值,然后ab,它们都可以评估为数值。然后apply+的结果应用于操作数的结果。

引用的表达式'(+ a b)不会评估它的参数。因此,+不会对某个过程进行评估,ab也不会被评估为数字。该值只是列表(+ a b)。如果您使用list进行此操作,则需要执行(list '+ 'a 'b)。如果你做(list + a b),你会得到3个变量,并得到(#<system-procedure:+> 2 3)之类的东西。

引用的表达式'(+ 2 3)很特殊,因为你有数字文字并且它们是自我评估的,但+仍然是一个符号,而不是看起来相同的评估变量,因为引用不评估它的参数。

(apply '+ '(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)))

答案 2 :(得分:0)

+绑定到大多数作用域中的过程,但它本身就是一个符号。它几乎总是受约束的程序是一个程序。 例如,在 (let ((+ "+")) +)+是一个字符串。在任何合理的状态下,你都会有类似

的东西

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