(print x) は評価したいものを正確に出力しますが、(eval x) は失敗しますが、x を実行すると動作します! 私は何が欠けていますか?
なぜこれがうまくいかないのか、または私が何かばかげたことをしているのか教えてください。
動的サイズのテーブルを印刷し、ラムダ変数を設定して、最終的にテーブル内の各セルの式を評価しようとしています。
ところで、eval が失敗する理由がわかりました。(eval x) はマクロレットを失っていますが、なぜ?!
これは機能します:
(defvar varlist '(a b c d))
(defvar vvars '(c d))
(defvar hvars '(a b))
(macrolet ((AlternateVariable (var &rest body)
`(dolist (,var '(nil t)) ,@body))
(AlternateVariables (varlist &rest body)
(if (null varlist)
(cons 'progn body)
`(AlternateVariable ,(car varlist)
(AlternateVariables ,(cdr varlist) ,@body)))))
(let ((listvarlist (cons 'list varlist)))
(print
`(AlternateVariables ,(reverse vvars)
(AlternateVariables ,(reverse hvars)
(format t "row=~S~%" ,listvarlist) ))))
nil)
そして、それは私が望むものを印刷します:
(alternatevariables (d c)
(alternatevariables (b a) (format t "row=~S~%" (list a b c d))))
その「print」を「eval」に変更すると、
; in: alternatevariables (d c)
; (B A)
; caught warning:
; undefined variable: a
しかし、(マクロレット内で) 印刷されたものを実行すると、動作します!
(macrolet ((AlternateVariable (var &rest body)
`(dolist (,var '(nil t)) ,@body))
(AlternateVariables (varlist &rest body)
(if (null varlist)
(cons 'progn body)
`(AlternateVariable ,(car varlist)
(AlternateVariables ,(cdr varlist) ,@body)))))
(alternatevariables (d c)
(alternatevariables (b a) (format t "row=~S~%" (list a b c d))))
nil)
そしてそれは印刷します
row=(nil nil nil nil)
row=(t nil nil nil)
row=(nil t nil nil)
row=(t t nil nil)
row=(nil nil t nil)
row=(t nil t nil)
row=(nil t t nil)
row=(t t t nil)
row=(nil nil nil t)
row=(t nil nil t)
row=(nil t nil t)
row=(t t nil t)
row=(nil nil t t)
row=(t nil t t)
row=(nil t t t)
row=(t t t t)
nil
「eval は悪」と聞いたことがありますが、正しい評価順序を取得し、いくつかの引数を評価するためにバッククォートが必要ですが、他の引数は評価しません。Print は優れたデバッグ ツールですが、eval では何かが欠けています。eval はマクロレットを失いますか?
! それでおしまい。これら 2 つのマクロレット マクロを defmacros として定義すると、eval が機能します。
どうして?!Eval はマクロレットを失っています。(私はマクロレットを初めて使用し、Lisp の天才ではありません)
または、eval なしでこれを行うにはどうすればよいですか?
私のコードに関する一般的なメモもいいでしょう。これは複雑すぎますか?
また、マクロでエラーが発生すると、厄介なエラー メッセージが表示されるようです。それについて何か助けはありますか?
$ sbcl
これは、ANSI Common Lisp の実装である SBCL 1.1.2-1.fc18 です。