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)