Вопрос

I am trying to evaluate a formula in scheme:

(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)

reading http://docs.racket-lang.org/guide/eval.html that should return #t but when I run it, it returns #f. Could you please tell me what I misunderstood?

I tried also:

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

but I got the same result.

Many thanks!

Это было полезно?

Решение

In your definition of formula you have quoted ?country - that is the mistake. Here is the behavior (note, my Scheme's eval requires an additional environment argument):

(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

There are a couple of things to make this better. You don't really need the if (you'll get #t or #f as the result of or). You can pass an additional argument to eval-formula for the name of the country. Like so (with display removed):

> (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

If, in fact, you are given formula with (quote ?country) then you can produce a new formula with ?country unquoted with:

(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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top