引用是否忽略了自我评估标识符?

时间:2014-02-07 01:00:11

标签: scheme quote

我知道当你在repl 'a中输入时,它会输出a而不进行评估,在内部,在我的情况下,它会在鸡计划中花费(##core#quote a)

我知道数字和字符串的特殊之处在于它们是自我评估的符号。我想因为这个原因,quote似乎对它们没有任何影响。

例如:

(+ '1 '2 '3)
> 6
(+ (quote 1) (quote 2) (quote 3))
> 6

(string-append '"hello " '"world")
>"hello world"

但是要做以下事情

''1
(quote 1) => (#core#quote '1) => (#core#quote (#core#quote 1))

如果我们这样做:

(car ''a)
> quote

这证实了我的意思。然后,如果我们执行以下操作,我们应该按预期找到1.

(cadr ''1)
> 1

我是否正确在评估时忽略引用的自我评估标识符?因为如果我这样做

(define a '1)
a

它不会打印'1而是打印1.

3 个答案:

答案 0 :(得分:3)

您应该尝试做的是通过编写一个非常简单的评估器来了解评估的工作原理。例如(这是伪代码!):

(define (self-evaluating? form)
  ;; This might not be exactly right, might be missing one type or two,
  ;; but you get the idea.
  (or (null? form)
      (number? form) 
      (boolean? form) 
      (string? form) 
      (vector? form)
      (character? form)))

(define (eval form env)
  (cond ((self-evaluating? form)
         ;; Self-evaluating forms evaluate to themselves. 
         form)
        ((symbol? form)
         ;; A symbol is evaluating by looking it up in the environment.
         ;; Note that this is pseudocode, and lookup-in-environment is not
         ;; a standard function... 
         (lookup-in-environment form env))
        ((list? form)
         (eval-combination form env))))

(define (eval-combination form env)
  (case (car form)
    ((quote)
     ;; A quote special form is evaluated simply by returning the 
     ;; argument to quote.
     (second form))

    ((define)
     ;; We evaluate a definition by evaluating the body in the current
     ;; environment, and setting the variable to the result in that 
     ;; environment.
     ;;
     ;; Note again that this is pseudocode, and set-in-environment! is
     ;; not a standard function... 
     (set-in-environment! env (second form) (eval (third form) env)))

    ;; Other special forms
    ...

    ;; Default rule: evaluate all the subexpressions in the current 
    ;; environment; the first one should be a procedure, which we then
    ;; apply to the list of values of the succeeding ones.
    (else
     (apply (eval (car form) env) 
            (map (lambda (arg) (eval arg env)) (cdr form)))))))

通过手动跟踪该代码的执行情况(并且您可以忽略案例的env参数),您应该能够看到正在发生的事情。关于这样的评估者需要注意的关键是它非常正交:对于每种类型的表单,都有一个单独的规则来评估它,并且规则彼此不了解。这一切都是由这个逻辑推动的:

  1. 表格是原子还是组合(列表)?
  2. 如果表格是原子,是自我评估还是符号?
  3. 如果表格是组合,是特殊表格还是程序申请?我们唯一要考虑的是表单car

答案 1 :(得分:2)

你是对的。评估(quote <object>)会返回该对象。评估自我评估对象也会返回该对象。

你正在考虑倒退。当对象进行自我评估时,并不是忽略引用,而是自我评估对象有效引用自己。

答案 2 :(得分:2)

语法关键字定义自己的评估规则。例如:

(define <identifier> <inititailizer>)

不会评估<identifier>,但会评估<initializer>。语法关键字quote不评估其参数,但是当评估quote本身时,它返回其参数。所以,如果你写:

(define a '1)

评估'1,评估quote语法为the number 1

请注意,自我评估表达式在R7RS中定义为:

⟨self-evaluating⟩ −→ ⟨boolean⟩ | ⟨number⟩ | ⟨vector⟩
  | ⟨character⟩ | ⟨string⟩ | ⟨byte vector⟩