Lisp 的宏系统是否也可以扩展其注释语法?

Can Lisp's macro system also extend its commenting syntax?

I love Racket's#;。我想在我再次使用的每一种语言中看到它。它可以通过他们的宏系统添加到其他 Lisp 吗?还是注释字符破坏了宏系统读取代码的能力?

一个充分的答案将证明在除 Racket 之外的任何 Lisp 中构建了一个宏,它允许更改评论系统。你不需要实际实现 Racket 的 #;,但如果你这样做我会喜欢的。与 Racket 相似度最低的 Lisps,例如Clojure 或任何非 Scheme 将特别值得一看。

您要找的是#+(or)reader宏。

由于 (or) 的计算结果为 nil,条件始终为假,因此永远不会计算以下形式。

#; 不是宏,它是 Common lisp 所说的 readmacro:它所做的是在读取时定义的,不晚于此。旨在完全抑制输入的读取宏有点危险,因为需要有一种表达 'read the following thing, but ignore it' 的方式,并且只有在任何 other readmacros 表现良好时才有可能:没有什么可以阻止某人定义一个即使阅读被抑制也会产生一些副作用的 readmacro。

然而,CL 中行为良好的读取宏(包括所有标准读取宏和标准 reader 的其余部分)不会这样做:它们会监听读取是否被抑制,并据此行事。

CL 允许您通过使用其对功能的条件化来作为标准执行此操作,特别是 #+(or) <expr> 将始终跳过 <expr>.

但您可以定义自己的:#; 未预定义,因此您可以定义它:

(set-dispatch-macro-character
 #\# #\;
 (lambda (stream char n)
   (declare (ignore char))
   (let ((*read-suppress* t))
     (dotimes (i (or n 1) (values))
       (read stream)))))

在此之后,或者至少使用经过更好测试的版本,然后 #; <expr>(或显然 #;<expr>)将读取为空格,并且 #2; ... ... 将跳过两个后续表达式:

> (let ((x #;1 #2; 2 3 4)) x)
4