17.4 函数式语法 (Functional Syntax)
另一个可以改善的空间是消息调用的语法。 tell
本身是无谓的杂乱不堪,这也使得动词在第三顺位才出现,同时代表着我们的程序不再可以像一般 Lisp 前序表达式那样阅读:
(tell (tell obj 'find-owner) 'find-owner)
我们可以使用图 17.5 所定义的 defprop
宏,通过定义作为函数的属性名称来摆脱这种 tell
语法。若选择性参数 meth?
为真的话,会将此属性视为方法。不然会将属性视为槽,而由 rget
所取回的值会直接返回。一旦我们定义了属性作为槽或方法的名字,
(defmacro defprop (name &optional meth?)
`(progn
(defun ,name (obj &rest args)
,(if meth?
`(run-methods obj ',name args)
`(rget ',name obj)))
(defun (setf ,name) (val obj)
(setf (gethash ',name obj) val))))
(defun run-methods (obj name args)
(let ((meth (rget name obj)))
(if meth
(apply meth obj args)
(error "No ~A method for ~A." name obj))))
图 17.5: 函数式语法
(defprop find-owner t)
我们就可以在函数调用里引用它,则我们的代码读起来将会再次回到 Lisp 本来那样:
(find-owner (find-owner obj))
我们的前一个例子在某种程度上可读性变得更高了:
> (progn
(setf scoundrel (obj)
patriot (obj)
patriotic-scoundrel (obj scoundrel patriot))
(defprop serves)
(setf (serves scoundrel) 'self
(serves patriot) 'country)
(serves patriotic-scoundrel))
SELF
T
当前内容版权归 readthedocs 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 readthedocs .