对多个原子使用读取时条件化

Use read-time conditionalization on several atoms

我想使用 Lisp 的读取时条件化功能来合并我的代码的两个版本,旧的和新的。我有类似的东西:

'(ant bee #+new cat #+new dog #+new eel fish)

所以旧版本是:

'(ant bee fish)

而新版本,当定义了特性 new 时,是:

'(ant bee cat dog eel fish)

有没有更简洁的写法,只出现一次#+new

如果您还可以使用反引号,这里有一个至少适用于三种 Common Lisp 实现的解决方案。您可以简单地对列表进行反引号,然后在 comma-at 拼接列表之前使用条件:

CL-USER> `(a b #+new,@'(c d e) f)
(A B F)

CL-USER> (push :new *features*)
...

CL-USER> `(a b #+new,@'(c d e) f)
(A B C D E F)

在文档部分 2.4.8.17 Sharpsign Plus,我们读到(强调):

#+ operates by first reading the feature expression and then skipping over the form if the feature expression fails. While reading the test, the current package is the KEYWORD package. Skipping over the form is accomplished by binding *read-suppress* to true and then calling read.

没有反引号的通用实现,所以我不能完全确定它是否完全可移植。我们假设 ,@<something> 将被读作 一种形式 ,因此它被跳过了。如果它有可能被处理为不止一种形式,这将行不通。我已经在 Clozure CL、SBCL 和 CLISP 中对其进行了测试,它适用于所有这些。

这样的事情会有帮助吗:

#+new
(defvar *new-items* '(cat dog eel))
#-new
'(ant bee fish)
#+new
(append '(ant bee fish) *new-times*)

更便携?不完全是 #+new 的一种用途,但它使它的使用不那么分散。