Lisp 注释约定

Lisp 关于不同类型注释使用多少分号(以及不同数量分号的缩进级别应该是多少)的约定是什么?

另外,关于何时使用分号注释和何时使用 #|multiline comments|#(假设它们存在并且存在于多个实现中) ,是否有任何约定?

53441 次浏览

与其在这里描述它,不如看看 这一页。它讨论的是 Emacs Lisp,但是所有 Lisp (和方案)的约定都是相同的。

在 Common Lisp 中:

;;;; At the top of source files


;;; Comments at the beginning of the line


(defun test (a &optional b)
;; Commends indented along with code
(do-something a)                      ; Comments indented at column 40, or the last
(do-something-else b))                ; column + 1 space if line exceeds 38 columns

注意: Emacs 不能很好地字体化 #| |#,但正如 Rainer 在评论中建议的那样,尝试使用 #|| ||#代替。

我想说没有使用这个的规则,但我认为它更快的注释大量的代码,或插入一些长的描述,分号只是在编辑的方式,像巨大的 BNF 列表或类似的。

禁用代码有一个巧妙的方法,就是给表达式加上 #+(or)的前缀:

(defun test (a &optional b)
#+(or)
(do-something a)
(do-something-else b))

注意: #+nil通常也可以工作,除非你碰巧有一个 nil:nil的功能。#+(or)的优点是,您可以通过注释掉它或者将它更改为 #+(and)来轻松地编辑它,或者实际上包含一组您真正希望读取表达式的特性。

在运行 Lisp 时,SLIME 通过将表单 (do-something a)字体化为注释来提供帮助。

除了 Common Lisp 特殊的注释语法和技巧,比如 #| |##+(or)或者更常见的 #+nil,我相信分号规则在其他 Lisp 中也被广泛采用。


下面是 说明书的一段摘录,请注意目前关于单个分号的做法是如何发生分歧的:

2.4.4.2分号风格说明

有些文本编辑器根据注释开头的分号数对所需的缩进进行假设。下面的样式约定是常见的,尽管绝不是普遍的。

2.4.4.2.1使用单一分号

以单个分号开头的注释都与右侧的同一列对齐(有时称为“注释列”)。此类注释的文本通常仅适用于其出现的行。有时两个或三个包含一个单独的句子在一起; 这有时是通过缩进所有,但第一个与一个额外的空格(后分号)。

2.4.4.2.2使用双分号

以双分号开头的注释都对齐到与窗体在代码中的相同位置相同的缩进级别。这种注释的文本通常描述注释发生时程序的状态,注释后面的代码,或者两者兼而有之。

2.4.4.2.3使用三重分号

以三重分号开头的注释都对齐到左边距。它们通常在定义或定义集之前使用,而不是在定义内使用。

2.4.4.2.4四重分号的使用

以四个分号开头的注释都与左边距对齐,通常只包含一小段文本,作为后面代码的标题,并且可能用于程序的页眉或页脚,以便将代码作为硬拷贝文档呈现。

2.4.4.2.5分号的样式示例

;;;; Math Utilities


;;; FIB computes the the Fibonacci function in the traditional
;;; recursive way.


(defun fib (n)
(check-type n integer)
;; At this point we're sure we have an integer argument.
;; Now we can get down to some serious computation.
(cond ((< n 0)
;; Hey, this is just supposed to be a simple example.
;; Did you really expect me to handle the general case?
(error "FIB got ~D as an argument." n))
((< n 2) n)             ;fib[0]=0 and fib[1]=1
;; The cheap cases didn't work.
;; Nothing more to do but recurse.
(t (+ (fib (- n 1))     ;The traditional formula
(fib (- n 2)))))) ; is fib[n-1]+fib[n-2].

Common Lisp 样式(包括注释约定)的标准参考是 Peter Norvig 和 Kent Pitman 的 良好 Lisp 编程风格教程

多行注释 # | | # 经常用于注释掉大量的 Lisp 代码或示例代码。由于一些 Emacs 实现似乎难以解析它们,所以一些实现使用了 # | | | # 。

有关分号的使用,请参阅盖伊 · L · 斯蒂尔(Guy L. Steele Jr.)1984年出版的《数字出版社,Common Lisp the Language》(第348页)一书中的注释示例:

;;;; COMMENT-EXAMPLE function.
;;; This function is useless except to demonstrate comments.
;;; (Actually, this example is much too cluttered with them.)


(defun comment-example (x y)      ;X is anything; Y is an a-list.
(cond ((listp x) x)             ;If X is a list, use that.
;; X is now not a list.  There are two other cases.
((symbolp x)
;; Look up a symbol in the a-list.
(cdr (assoc x y)))        ;Remember, (cdr nil) is nil.
;; Do this when all else fails:
(t (cons x                ;Add x to a default list.
'((lisp t)       ;LISP is okay.
(fortran nil)  ;FORTRAN is not.
(pl/i -500)    ;Note that you can put comments in
(ada .001)     ; "data" as well as in "programs".
;; COBOL??
(teco -1.0e9))))))

在本例中,注释可以以一到四个分号开头。

  • 单分号注释都与右边的同一列对齐; 通常每个注释只涉及其旁边的代码。有时候,注释的长度足以占据两行或三行; 在这种情况下,通常将注释的连续行缩进一个空格(在分号之后)。

  • 双分号注释与代码的缩进级别对。空格通常跟在两个分号后面。这样的注释通常描述程序在该点的状态或注释后面的代码部分。

  • 三分号注释与左边对齐。它们通常记录整个程序或大的代码块。

  • 四重分号注释通常表示整个程序或大代码块的标题。

当人们谈论惯例而没有真正解释在行尾注释中混合使用双分号和单分号的错误时,这是令人恼火的。“大会说... ... 啦啦啦啦... ...”。但是为什么这么说呢?这就是众所周知的“祖母的规则”如何成为现实。“我们为什么要这么做?嗯,因为我们的祖母是这样教我们的,而且她对此非常严格... ...”:)

大多数情况下,在所谓的“行尾”注释中使用双分号不会有问题。如果你把页边注释和常规注释放在同一块里,这可能会成为一个问题,例如:

   (defn foo []
(bar) ;; yup, bar
;; let's now do a zap
(zap))

因此,如果你使用 Emacs 的 fill-paragraph特性-它会自动对齐这两个注释,就好像它们是一个单独的语句。

   (defn foo []
(bar) ;; yup, bar
;; let's now do a zap
(zap))

这可能不是你想要的,所以如果你用一个分号来代替:

   (defn foo []
(bar) ; yup, bar
;; let's now do a zap
(zap))

它将使它们保持预期的(未对齐的)状态。所以,我想人们不会一遍又一遍地解释这个问题,而是制定了一个规则——对 使用单个分号作为边距注释