在 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 程序员来说是不和谐的,否则他们大部分时间都不会看到它们。