其中一位花时间评论my other question关于Clojure / LISP语法的人指出,我没有用标准的LISP方式编写示例代码。所以他很友好地重写了代码片段,这是一个很大的帮助。但它在我的脑海里提出了另一个问题。为什么会这样:
(if (= a something)
(if (= b otherthing)
(foo)))
这是标准的LISP格式,可以使用这种形式:
(if (= a something)
(if (= b otherthing)
(foo)
)
)
由于我的C ++开发背景,这就是我天真地格式化这段代码的方式。我想知道后一种格式化是否有任何好处,或者它只是一种根深蒂固的标准(如QWERTY键盘)。我不是要争论 - 我很难理解为什么第一种形式会更好。第二种形式帮助我更容易地看到代码结构。
答案 0 :(得分:37)
Lisp代码缩进的方式有点像Python中的重要空白,除了它当然是可选的。基本的经验法则是,如果项目不在同一条线上,则将项目垂直放置在另一个列表中。
(a (b (c (d e)
(f g))
(h i j))
(k l m n))
如果没有查看括号,您可以看到(d e)
和(f g)
是c
的参数,(c (d e) (f g))
和(h i j)
是{{}的参数1}},b
和(b (c (d e) (f g)) (h i j))
是(k l m n)
的参数。
使用您的示例,它应该更正确地格式化如下:
a
现在缩进的级别变得有意义,你不再需要依赖平衡括号来获取那些信息,并且因为将它们放在与结束语句相同的行上更紧凑,这就是lispers所做的。当然,并不要求Lisp代码以这种方式格式化,但它是人们使用并且可以依赖的相当标准的约定。
答案 1 :(得分:37)
额外行上的右括号对查看代码结构没有帮助,因为您可以从缩进级别获取相同的信息。但是,第二种形式占用了几乎两倍的行,迫使您在阅读代码时更频繁地滚动。
如果您需要更仔细地检查嵌套括号,突出显示匹配括号的编辑器将对您有所帮助。当匹配的括号不太远时,这也会更容易。
如果表达式太长且太复杂而无法轻松阅读,那么也可能表明您应该将部分功能提取到单独的函数中。
答案 2 :(得分:3)
简单的答案是,你的方式不是Lisp的漂亮打印机做事的方式。拥有一个真正的格式对于代码来说总是一件好事,而pprint宏为您提供了内置于该语言中的格式。
当然,因为 pprint宏存在,所以你不一定非常需要遵循标准的代码格式,因为人们可以通过pprint运行代码并获得他们习惯的代码。但是,由于其他人都使用pprint,或者手动逼近它,如果你不这样做,你将很难阅读代码,并且你没有一个简单的宏可以将他们的代码变成你的首选格式。
答案 3 :(得分:1)
您可以使用Sreafctor包重新格式化Lisp代码:Homepage。
一些演示:
可用命令:
srefactor-lisp-format-buffer
:格式化整个缓冲区srefactor-lisp-format-defun
:格式当前的defun游标位于srefactor-lisp-format-sexp
:格式化当前的性别光标。srefactor-lisp-one-line
:将同一级别的当前性别变为一行;使用前缀参数,递归地将所有内部性别变为一行。格式化命令也可用于Common Lisp和Scheme。
如果有任何问题,请提交问题报告,我很乐意解决。
答案 4 :(得分:0)
当你有10个括号要关闭时,它变得非常笨重。
当我以前编写Lisp时,我在右括号之间留下了一个空格,用于在同一行上打开括号,其余部分用于简化计数,如下所示:
(if (= a something) (if (= b otherthing) (foo) ))
我想这些日子不再需要,因为编辑更有帮助。