对几个原子使用读时条件化

时间:2016-01-08 14:08:10

标签: lisp common-lisp

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

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

所以旧版本是:

'(ant bee fish)

和新版本在定义功能 new 时为:

'(ant bee cat dog eel fish)

有没有一种方法可以更简洁地写这个,只有一次出现#+ new

2 个答案:

答案 0 :(得分:5)

如果你也可以使用反引号,这里的解决方案至少可以在三个Common Lisp实现中使用。您可以简单地反引用该列表,然后在逗号拼接列表之前使用条件:

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中,我们读到了(强调添加):

  

#+通过首先读取要素表达式然后跳过表单进行操作(如果要素表达式失败)。在阅读测试时,   当前包是KEYWORD包。跳过表单是   通过将* read-suppress *绑定到true然后调用read来完成。

没有反引号的通用实现,因此我并不完全确定这是完全可移植的。我们依赖于,@<something>将被视为一个表单的假设,以便它跳过了什么。如果它可以作为多个表单处理,那么这不会起作用。我已经在Clozure CL,SBCL和CLISP中对它进行了测试,它适用于所有这些。

答案 1 :(得分:0)

这样的事情会有所帮助:

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

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