【发布时间】:2015-03-12 08:22:25
【问题描述】:
给定以下函数,在 REPL 中输入:
(defun animalp (thing)
(if (member thing '(dog cat snail mouse)) t))
问起来很简单:
(animalp 'dog)
拆分成包后事情变得更加复杂:
(in-package :common-lisp-user)
(defpackage :animalia
(:use :common-lisp)
(:export :animalp))
(in-package :animalia)
(defun animalp (thing)
(if (member thing '(dog cat snail mouse)) t))
现在,人们仍然可以问同样的问题:
(animalia:animalp 'animalia::dog)
但它越来越乱了。 (我对“animalia:animalp”并不在意,问题在于大量的动物。)本质上我想问:
(animalia:animalp 'dog)
符号(狗、猫等)没有任何属性 - 基本上我一直将它们用作字符串比较的简写:
(if (member "dog" '("dog" "cat" "mouse" "snail")
:test #'string-equal) t)
所以我的问题是关于最佳实践。我不喜欢使用字符串——尤其是当 (eq 'dog 'dog) 在单个包中如此简单时。另一方面,我也没有对 (defpackage ... (:export :dog :cat ...)) 的前景感到欣喜若狂,并且需要用一个包(animialia:dog 等)来限定每只动物。最后一个明显的解决方案是让所有的动物关键字,如:
(if (member :dog '(:dog :cat :mouse :snail)) t)
但即使这样看起来也有点脏。
有哪些最佳实践解决方案可以实现我想要的,而不会弄得一团糟或诉诸幻想、丑陋和潜在脆弱解决方案的演变?
【问题讨论】:
标签: lisp common-lisp