0

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!

1 Answers1

0

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)
GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • The problem is that I receive some formulas and some values for variables (the ones that start with ?) and I have to return true or false. I tried t debug it and it evaluates: (if (or (equal? (quote ?country) (quote United-States)) (equal? (quote ?country) (quote England))) #t #f) . I am trying to remove that "quote" in front of ?country. – Ioana Alexandra Antoche Mar 29 '13 at 21:49
  • My question is how I can unquote ?country – Ioana Alexandra Antoche Mar 29 '13 at 21:54
  • The only option that I can see it to rewrite `formula` to replace `(quote ?country)` with just `?country`. If you try to redefine `quote` then that redefinition will apply to `(quote United-States)` and to `(quote England)` and cause evaluation problems. – GoZoner Mar 29 '13 at 22:08