【发布时间】:2010-03-26 12:22:47
【问题描述】:
以下代码有问题:http://lisper.ru/apps/format/96
问题出在“正常化”功能中,该功能不起作用。
它在第五行失败:(zero-p a indexes i)
(defun normalize (a &optional indexes i)
"Returns normalized A."
(progn
(format t "Data=~A ~A ~A" a indexes i)
(if (zero-p a indexes i)
a ;; cannot normalize empty vector
(let* ((mmm (format t "Zero?=~a" (zero-p a indexes i)))
(L (sqrt (+ (do-op-on * a :x a :x indexes i indexes i)
(do-op-on * a :y a :y indexes i indexes i)
(do-op-on * a :z a :z indexes i indexes i))))
(mmm (format t "L=~a" L))
(L (/ 1D0 L))
(mmm (format t "L=~a" L))) ; L=1/length(A)
(make-V3 (* (ref-of a :x indexes i) l)
(* (ref-of a :y indexes i) l)
(* (ref-of a :z indexes i) l))))))
在函数“normalize”中,我将宏称为“zero-p”,后者又调用宏“ref-of”,它是链中的最后一个。
(defmacro zero-p (v &optional indexes index)
"Checks if the vector is 'almost' zero length."
`(and (< (ref-of ,v :x ,indexes ,index) *min+*)
(< (ref-of ,v :y ,indexes ,index) *min+*)
(< (ref-of ,v :z ,indexes ,index) *min+*)
(> (ref-of ,v :x ,indexes ,index) *min-*)
(> (ref-of ,v :y ,indexes ,index) *min-*)
(> (ref-of ,v :z ,indexes ,index) *min-*)))
这里是参考:
(defmacro ref-of (values coordinate &optional indexes index)
"Please see DATA STRUCTURE for details."
(if indexes
(cond ((eq coordinate :x) `(aref ,values (aref ,indexes ,index)))
((eq coordinate :y) `(aref ,values (+ 1 (aref ,indexes ,index))))
((eq coordinate :z) `(aref ,values (+ 2 (aref ,indexes ,index))))
(T (error "The symbol ~S is not :X, :Y or :Z." coordinate)))
(cond ((eq coordinate :x) `(aref ,values 0))
((eq coordinate :y) `(aref ,values 1))
((eq coordinate :z) `(aref ,values 2))
(T (error "The symbol ~S is not :X, :Y or :Z." coordinate)))))
此外,在“规范化”中,我将宏称为“do-op-on”,它也称为“ref-of”。
(defmacro do-op-on (op name1 coord1 name2 coord2 &optional is1 i1 is2 i2)
"Example: (do-op-on * A :x B :y i n) == A[i[n]].x*B.y"
`(,op (ref-of ,name1 ,coord1 ,is1 ,i1) (ref-of ,name2 ,coord2 ,is2 ,i2)))
因此,我没有这个:(aref some-array 0) 我有(aref NIL NIL),它是在“ref-of”中创建的。
我想我在调用 (normalize A) 时丢失了符号 A。我只是觉得这个符号在宏扩展中无法生存。问题是,macroexpansoin 在 REPL 中独立地为每个宏工作。
谁能解释错误在哪里?
【问题讨论】:
-
你能比“不工作”更具描述性吗?哪个宏不起作用?想象一下,您是一名错误报告者。
-
感谢您的反馈!我澄清了这个问题。
-
你使用什么语言(Common Lisp?)和实现?
-
@Svante:我不想要函数调用。我为什么要这样做?
-
@avp:使代码易于理解(但我认为这已经在 Pillsy 的回答中得到了回答)。从您的评论“查看数据结构”中,我的印象是您可以通过使用 CLOS 大大降低代码复杂性(请参阅
defclass、defgeneric和defmethod的超规范,以及“对象重新定向”一章在免费书籍“实用通用 Lisp”中)。您的ref-of和do-op-on可能会消失,或者简化为defclass表单中的简单声明。
标签: macros lisp common-lisp