Mysterious Racket error: define: unbound identifier; кроме того, трансформатор синтаксиса приложения #%не связан: define
программа выдает ошибку:
define: unbound identifier;
also, no #%app syntax transformer is bound in: define
при вставке в 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*))
такое:
(define (eval-clause clause state)
(eval `(let ,state ,(cons 'or clause))))
производит
let: unbound identifier;
also, no #%app syntax transformer is bound in: let
это была моя попытка перевести следующую программу 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*))
и в парень:
(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*)
2 ответов
eval
сложно в рэкете. В соответствии с руководством по ракетке, 15.1.2, вам нужно подключиться к текущему пространству имен следующим образом
(define-namespace-anchor anc)
(define ns (namespace-anchor->namespace anc))
и затем добавить 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))
обратите внимание, что это не обязательно в 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*))
или, если вы хотите продолжить использование true
и false
С 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))))
Я бы написал общую версию Lisp немного проще:
(defun eval-clause (clause state)
(loop for (var value) in state
do (set var value))
(some #'eval clause))
форма цикла более описательна (так как мы можем избавиться от CAR
и NTH
) и EVAL
можно сразу использовать в