39

通常代码如下所示:

(one-thing
    (another-thing arg1 (f arg5 r))
    (another-thing arg1 (f arg5 r)))

为什么不喜欢这样?:

(one-thing
    (another-thing arg1 (f arg5 r))
    (another-thing arg1 (f arg5 r))
)

它允许更轻松地添加和删除“另一件事”行(无需删除和重新添加尾随右括号)。您也可以对那个单独的右括号(例如“;循环结束”)发表一些评论。

当我将使用第二种样式的代码与使用第一种样式的现有代码混合使用时有多糟糕?

4

8 回答 8

49

在 Lisp 和其他使用 S 表达式作为语法的语言中,括号主要是为了编译器的好处,而布局和缩进(编译器会忽略)是为了程序员的好处。

所以没有必要在自己的行上放置右括号:精心选择的换行符和缩进足以使结构清晰。

例如,

(defun clone-indirect-buffer-other-window (newname display-flag &optional norecord)
  "Like `clone-indirect-buffer' but display in another window."
  (interactive
   (progn
     (if (get major-mode 'no-clone-indirect)
         (error "Cannot indirectly clone a buffer in %s mode" mode-name))
     (list (if current-prefix-arg
               (read-buffer "Name of indirect buffer: " (current-buffer)))
           t)))
  (let ((pop-up-windows t))
    (clone-indirect-buffer newname display-flag norecord)))

从缩进来看,结构很清晰(对于经验丰富的 Lisp 程序员来说)。将一些右括号放在新行上不会添加任何内容:

(defun clone-indirect-buffer-other-window (newname display-flag &optional norecord)
  "Like `clone-indirect-buffer' but display in another window."
  (interactive
   (progn
     (if (get major-mode 'no-clone-indirect)
         (error "Cannot indirectly clone a buffer in %s mode" mode-name)
       )
     (list (if current-prefix-arg
               (read-buffer "Name of indirect buffer: " (current-buffer))
             )
           t)
     )
   )
  (let ((pop-up-windows t))
    (clone-indirect-buffer newname display-flag norecord)
    )
  )

我应该补充一点,几乎所有 Lisp 程序员都使用一个编辑器,它显示匹配的括号,执行自动缩进,并提供一个用户界面来直接处理平衡的表达式。例如,在 Emacs 中,M-(用于插入新表达式、M-)移过当前表达式的末尾、C-M-k删除点之后的表达式等等。

所以 Lisp 程序员永远不必手动计算括号来找出匹配的括号。


Taylor R. Campbell雄辩地表达了这一基本原理:

实际的括号字符只是词法标记,应为其分配很少的意义。Lisp 程序员不会单独检查括号,或者,Azathoth 禁止计算括号;相反,他们查看程序中表达的更高级别的结构,尤其是缩进所呈现的结构。Lisp 不是要编写一系列串行指令。它是关于通过对部分求和来构建复杂的结构。由部件组成复杂结构是 Lisp 程序的重点,从 Lisp 代码中应该很容易看出这一点。在演示文稿中随意放置括号对 Lisp 程序员来说是不和谐的,否则他们大部分时间都不会看到它们。

于 2010-11-29T15:24:00.950 回答
31

这里有两点需要说明:

  1. 约定本身很重要。坚持使用包装的括号意味着您的代码对其他 lisp 程序员来说更具可读性,如果您采用这种风格,您还将培养阅读他们的代码的实践

  2. 在大多数 lispers 眼中,将 s拆分)到自己的行上的优势实际上并不是优势。如果您使用的是半体面的编辑器,它将具有理解平衡表达式的命令,用于在它们之间移动、剪切、粘贴、转置等。所以您不需要

    )  ; end of the loop
    

    在 lisp 中比你需要的更多

    # end of the loop
    

    在一些对空格敏感的语言中,比如 Python

参见例如http://www.gnu.org/software/emacs/manual/html_node/emacs/Expressions.html

于 2010-11-29T15:09:43.593 回答
11

简短的回答:偏离公认的标准只会疏远潜在的贡献者。没有一种风格比另一种更好。

长答案http ://blog.fogus.me/2010/08/30/community-standards/

于 2010-11-29T15:09:53.830 回答
3

你喜欢什么!这是你的代码。

也就是说,您最终可能会将它们全部移回,以便您可以一次在屏幕上获得更多内容。确实,一段时间后您实际上不再看到括号了。

实际上,情况比这差一些。这些天,当我尝试使用心爱的 python 时,感觉我的代码没有括号就不能牢固地捆绑在一起,我担心它可能随时崩溃。

见鬼,记录几个键盘宏来将整个文件从一种风格换成另一种风格。(并了解如何使您的版本控制忽略仅空白更改。:-)

于 2010-11-29T15:45:14.293 回答
3

如果您使用 Emacs,则需要学习这些. 特别是,C-M-k使杀死一个平衡的表达就像杀死一条线一样容易。再加上平衡括号的突出显示,真的没有必要这样写。

另一方面,将所有这些)s 单独放在行上意味着您在屏幕上一次看到的代码更少,从而更难阅读和重构。

如果你不使用 Emacs,你至少应该使用支持这些基本操作的编辑器,否则用 lisp 编码会很痛苦。

于 2013-03-19T18:34:00.463 回答
1

括号不是为了可读性,而是为了计算机。程序员可以通过查看缩进来了解代码块的结束位置。此外,多个右括号共享一行意味着程序员可以在屏幕上一次查看更多代码。

于 2017-12-22T16:15:57.803 回答
1

节省垂直屏幕(和眼睛)的房地产空间很重要。

于 2015-09-07T17:26:57.300 回答
1

我认为一个很好的答案是问一个相关的问题:

为什么 Python 程序员不将关闭嵌套的字形放在自己的行上?

现在的答案很明显:没有这样的字形。事实证明,在 Lisp 中也没有这样的字形:是的,有一些 Lisp 阅读器需要的有点烦人()字符,但是人类不会像这样阅读 Lisp 代码:他们通过缩进和单词来阅读它。

于 2016-02-15T07:45:16.000 回答