简体   繁体   English

Lisp 的宏系统也可以扩展它的注释语法吗?

[英]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

What you are looking for is #+(or) reader macro.您正在寻找的是#+(or)阅读器宏。

Since (or) evaluates to nil , the condition is always false the following form is never evaluated.由于(or)的计算结果为nil ,因此条件始终为 false ,因此永远不会评估以下形式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM