[英]Can Lisp's macro system also extend its commenting syntax?
I love Racket's #;
我喜欢 Racket 的
#;
. . I want to see it in every language that I ever use again.
我想以我曾经再次使用的每一种语言看到它。 Can it be added to other Lisps via their macro systems?
它可以通过它们的宏系统添加到其他 Lisp 中吗? Or does the commenting character break the macro system's ability to read the code?
还是注释字符会破坏宏系统读取代码的能力?
A sufficient answer will demonstrate a macro being built in any Lisp other than Racket that allows for a change in the commenting system.一个充分的答案将证明在除 Racket 之外的任何 Lisp 中构建了一个宏,该宏允许更改评论系统。 You need not actually implement Racket's
#;
你不需要实际实现 Racket 的
#;
, but I would like it if you do. ,但如果你愿意,我会喜欢的。 Lisps with the least similarity to Racket, eg Clojure or any non-Scheme will be particularity nice to see.
与 Racket 最不相似的 Lisp,例如 Clojure 或任何非方案将特别好看。
#;
isn't a macro, it's what Common lisp would call a readmacro : what it does is defined at read time, not later than that.不是宏,它是 Common lisp 所称的readmacro :它的作用是在读取时定义的,不迟于那个。 Read macros which aim to completely suppress input are mildly perilous because there needs to be a way of saying 'read the following thing, but ignore it', and that's only possible if any other readmacros behave well: there's nothing to stop someone defining a readmacro which produces some side-effect even if reading is suppressed.
旨在完全抑制输入的读取宏有点危险,因为需要一种方式来表示“读取以下内容,但忽略它”,并且只有在任何其他readmacros 表现良好时才有可能:没有什么可以阻止某人定义 readmacro即使阅读被抑制,也会产生一些副作用。
However, well-behaved readmacros (which includes all of the standard ones and the rest of the standard reader) in CL won't do that: they'll listen to whether reading is being suppressed, and behave accordingly.但是,在 CL 中表现良好的 readmacros(包括所有标准的 readmacros 和标准阅读器的 rest)不会这样做:它们会听取阅读是否被抑制,并做出相应的行为。
CL allows you to do this as standard by using its conditionalisation on features, and in particular #+(or) <expr>
will always skip <expr>
. CL 允许您通过使用其对功能的条件化来将其作为标准来执行,特别是
#+(or) <expr>
将始终跳过<expr>
。
But you can define your own: #;
但是你可以定义你自己的:
#;
is not predefined so you can define it:未预定义,因此您可以定义它:
(set-dispatch-macro-character
#\# #\;
(lambda (stream char n)
(declare (ignore char))
(let ((*read-suppress* t))
(dotimes (i (or n 1) (values))
(read stream)))))
After this, or at least with a better tested version of this, then #; <expr>
在此之后,或者至少使用经过更好测试的版本,然后
#; <expr>
#; <expr>
(or obviously #;<expr>
) will read as whitespace, and #2; ... ...
#; <expr>
(或显然是#;<expr>
)将读作空格,而#2; ... ...
#2; ... ...
will skip two following expressions: #2; ... ...
将跳过以下两个表达式:
> (let ((x #;1 #2; 2 3 4)) x)
4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.