带报价的评估方案功能

时间:2013-03-29 20:34:54

标签: scheme let

我正在尝试评估方案中的公式:

(define formula '(if (or (equal? '?country 'United-States) (equal? '?country 'England))
                  #t
                  #f))
(define (eval-formula formula)
  (eval `(let ([?country 'United-States])
           (display formula) (newline)
           (display ?country) (newline)
           ,formula)))

(eval-formula formula)

读取应返回#t的http://docs.racket-lang.org/guide/eval.html但是当我运行它时,它会返回#f。你能告诉我我误解了什么吗?

我也试过了:

(define formula '(if (or (equal? '?country 'United-States) (equal? '?country 'England))
                  #t
                  #f))
(define ?country 'United-States)
(eval formula)

但我得到了相同的结果。

非常感谢!

1 个答案:

答案 0 :(得分:0)

formula的定义中,您引用了?country - 这就是错误。这是行为(请注意,我的Scheme eval需要额外的environment参数:

(define formula '(if (or (equal? ?country 'United-States) (equal? ?country 'England))
                  #t
                  #f))

(define (eval-formula formula)
  (eval `(let ([?country 'United-States])
           (display formula) (newline)
           (display ?country) (newline)
           ,formula)
    (interaction-environment)))

> (eval-formula formula)
(if (or (equal? ?country 'United-States) (equal? ?country 'England)) #t #f)
United-States
#t

有几件事要做得更好。您实际上不需要if#t#f作为or的结果。您可以将另一个参数传递给eval-formula以获取该国家/地区的名称。像这样(删除了display):

> (define (eval-formula formula country)
  (eval `(let ([?country ',country]) ,formula)
    (interaction-environment)))
> (eval-formula formula 'United-States)
#t
> (eval-formula formula 'England)
#t
> (eval-formula formula 'Japan)
#f

事实上,如果您formula获得了(quote ?country),那么您可以使用formula生成一个新的?country

(define (unquoting identifiers expression)
  (if (null? expression)
      '()
      (let ((next (car expression)))
        (cons (cond ((not (pair? next)) next)
                    ((not (null? next))
                     (if (and (eq? 'quote (car next))
                              (member (cadr next) identifiers))
                         (cadr next) ; unquote here
                         (unquoting identifiers next)))
                    (else 'error))
          (unquoting identifiers (cdr expression))))))

 (set! formula (unquoting '(?country) formula)