Mysterious Racket error: define: unbound identifier; also, no #%app syntax transformer is bound in: define

前端 未结 2 1116
旧时难觅i
旧时难觅i 2021-01-02 13:12

This program produces an error:

define: unbound identifier;
 also, no #%app syntax transformer is bound in: define

When pasted into the RE

2条回答
  •  独厮守ぢ
    2021-01-02 13:55

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

提交回复
热议问题