This program produces an error:
define: unbound identifier;
also, no #%app syntax transformer is bound in: define
When pasted into the RE
eval
is tricky in Racket. As per Racket Guide, 15.1.2, you need to hook into the current namespace as follows
(define-namespace-anchor anc)
(define ns (namespace-anchor->namespace anc))
and then add ns
to every call to eval
:
(define (eval-clause clause state)
(for ([x state])
(eval `(define ,(first x) ,(second x)) ns))
(eval (cons 'or (map (curryr eval ns) clause)) ns))
Note that this is not necessary in the REPL, as explained in the document referenced above.
However, it's probably a better idea to create a specific namespace for your definitions so that they don't get mixed up with your own module's definitions:
(define my-eval
(let ((ns (make-base-namespace)))
(lambda (expr) (eval expr ns))))
(define *state* '((a #f) (b #t) (c #t) (d #f)))
(define *clause* '(a (not b) c))
(define (eval-clause clause state)
(for ([x state])
(my-eval `(define ,(first x) ,(second x))))
(my-eval (cons 'or (map my-eval clause))))
(displayln (eval-clause *clause* *state*))
or, if you want to continue using true
and false
from racket/bool
, define my-eval
as follows;
(define my-eval
(let ((ns (make-base-namespace)))
(parameterize ((current-namespace ns))
(namespace-require 'racket/bool))
(lambda (expr) (eval expr ns))))
I would write the Common Lisp version slightly simpler:
(defun eval-clause (clause state)
(loop for (var value) in state
do (set var value))
(some #'eval clause))
The LOOP form is more descriptive (since we can get rid of CAR
and NTH
) and EVAL
can be directly used in the SOME
function.