为什么 AND、OR 按预期工作但 XOR 显示错误?

Why does AND, OR work as expected but an error is shown with XOR?

(define-syntax e.g.
  (syntax-rules (===>)
    ((e.g. proposition)
     (unless proposition
       (error "invalid proposition: "'proposition)))
    ((e.g. proposition ===> value)
     (let ((result proposition))
       (unless (equal? proposition value)
         (error "invalid proposition: "'proposition
                ", expected "value", got "result))))))

(define my-eval
  (let ((ns (make-base-namespace)))
    (lambda (expr) (eval expr ns))))

(e.g. (my-eval '(and #t #t)) ===> #t)
(e.g. (my-eval '(and #t #f)) ===> #f)
(e.g. (my-eval '(or #t #f)) ===> #t)
(e.g. (my-eval '(or #f #f)) ===> #f)
(e.g. (my-eval '(xor #t #t)) ===> #f)
(e.g. (my-eval '(xor #t #f)) ===> #t)

它适用于 AND、OR 但适用于 XOR:

异或:未定义; 不能在定义之前引用标识符。

即使在 REPL 中 tough 似乎也能正常工作:

(xor #t #f)

t

您需要将 racket/bool 提供到 my-eval 使用的命名空间中,它提供 xor。一种方法是在 xor 测试之前 运行 (my-eval '(require racket/bool))

The question is who has time to read whole documents like that?

您不必一口气读完所有内容,但这就是信息所在,而且 Racket 有很多很棒的文档。

eval 在 Racket 中可能有点滑;您需要完成评估 eval 表达式的名称空间的设置。一种方法是使用 parameterize 创建一个空的命名空间。这需要在 lambda 表达式内部发生,即评估 eval 的环境,并且您需要确保 racket/baseracket/bool 都是 required:

#lang racket

(define-syntax e.g.
  (syntax-rules (===>)
    ((e.g. proposition)
     (unless proposition
       (error "invalid proposition: " 'proposition)))
    ((e.g. proposition ===> value)
     (let ((result proposition))
       (unless (equal? proposition value)
         (error "invalid proposition: " 'proposition
                ", expected " value ", got " result))))))

(define my-eval
  (lambda (expr)
    (parameterize ([current-namespace (make-base-empty-namespace)])
      (namespace-require 'racket/base)
      (namespace-require 'racket/bool)
      (eval expr))))

(e.g. (my-eval '(and #t #t)) ===> #t)
(e.g. (my-eval '(and #t #f)) ===> #f)
(e.g. (my-eval '(or #t #f)) ===> #t)
(e.g. (my-eval '(or #f #f)) ===> #f)
(e.g. (my-eval '(xor #t #t)) ===> #f)
(e.g. (my-eval '(xor #t #f)) ===> #t)