神秘的球拍错误:定义:未绑定的标识符; 此外,没有#%app语法变换器绑定在:define中

KIM*_*oon 8 lisp racket

该程序产生错误:

define: unbound identifier;
 also, no #%app syntax transformer is bound in: define
Run Code Online (Sandbox Code Playgroud)

当粘贴到REPL中(确切地说,最后一行:(displayln(eval-clause 子句 状态))),它可以工作.在定义窗口中运行时,它会失败.我不知道为什么.

#lang racket
(define *state* '((a false) (b true) (c true) (d false)))
(define *clause* '(a (not b) c))

(define (eval-clause clause state)
  (for ([x state])
    (eval `(define ,(first x) ,(second x))))
  (eval (cons 'or (map eval clause))))

(displayln (eval-clause *clause* *state*))
Run Code Online (Sandbox Code Playgroud)

这个也是:

(define (eval-clause clause state)
  (eval `(let ,state ,(cons 'or clause))))
Run Code Online (Sandbox Code Playgroud)

产生

let: unbound identifier;
 also, no #%app syntax transformer is bound in: let
Run Code Online (Sandbox Code Playgroud)

这是我尝试翻译以下Common Lisp程序:Common Lisp在这里获胜?

; (C) 2013 KIM Taegyoon
; 3-SAT problem
; https://groups.google.com/forum/#!topic/lisp-korea/sVajS0LEfoA
(defvar *state* '((a nil) (b t) (c t) (d nil)))
(defvar *clause* '(a (not b) c))

(defun eval-clause (clause state)
  (dolist (x state)
    (set (car x) (nth 1 x)))
  (some #'identity (mapcar #'eval clause)))

(print (eval-clause *clause* *state*))
Run Code Online (Sandbox Code Playgroud)

Paren:

(set *state* (quote ((a false) (b false) (c true) (d false))))
(set *clause* (quote (a (! b) c)))
(defn eval-clause (clause state)
  (for i 0 (dec (length state)) 1
    (set x (nth i state))
    (eval (list set (nth 0 x) (nth 1 x))))  
  (eval (cons || clause)))
(eval-clause *clause* *state*)
Run Code Online (Sandbox Code Playgroud)

use*_*lpa 17

eval在Racket中很棘手.根据Racket Guide,15.1.2,您需要按如下方式挂接到当前名称空间

(define-namespace-anchor anc)
(define ns (namespace-anchor->namespace anc))
Run Code Online (Sandbox Code Playgroud)

然后添加ns到每个调用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))
Run Code Online (Sandbox Code Playgroud)

请注意,这在REPL中不是必需的,如上面引用的文档中所述.

但是,为定义创建特定的命名空间可能更好一点,这样它们就不会与您自己的模块定义混淆:

(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*))
Run Code Online (Sandbox Code Playgroud)

或者,如果你想继续使用truefalse来自racket/bool,定义my-eval如下;

(define my-eval
  (let ((ns (make-base-namespace)))
    (parameterize ((current-namespace ns))
      (namespace-require 'racket/bool))
    (lambda (expr) (eval expr ns))))
Run Code Online (Sandbox Code Playgroud)