Lisp代码格式
其中一位花时间评论我关于Clojure / LISP语法的其他问题的人指出,我没有用标准的LISP方式编写示例代码。 所以他很友善地重写代码片段,这是一个很大的帮助。 但是在我的脑海里又提出了另一个问题。 为什么会这样:
(if (= a something) (if (= b otherthing) (foo)))
这是标准的LISP格式可以select这种forms:
(if (= a something) (if (= b otherthing) (foo) ) )
这是我的天真格式化代码的方式,因为我的C ++开发背景。 我想知道是否有利于后者的格式,或者它只是一个根深蒂固的标准(如QWERTY键盘)。 我不想争论 – 我很难理解为什么第一种forms更可取。 第二种forms帮助我更容易地看到代码结构。
多余行上的右括号并不能真正帮助您查看代码的结构,因为您可以从缩进级别获取相同的信息。 然而,第二种forms几乎占用了两倍的行数,迫使你在阅读代码时更频繁地滚动。
如果您需要更仔细地检查嵌套圆括号,那么突出显示匹配圆括号的编辑器将对您有所帮助。 当匹配的圆括号不太远时,这也会更容易。
如果expression式太长而且复杂以致不易阅读,那么也可能表示您应该将部分function提取到单独的函数中。
Lisp代码缩进的方式有点像Python中的重要空白,只不过它是可选的。 基本的经验法则是,如果项目不在同一行,则将项目垂直放置在列表中。
(a (b (c (de) (fg)) (hij)) (klmn))
(c (de) (fg))
(de)
和(fg)
都是c
参数, (c (de) (fg))
, (hij)
是b
参数, (b (c (de) (fg)) (hij))
(klmn)
(b (c (de) (fg)) (hij))
和(klmn)
是a
参数。
用你的例子,应该更正确地格式化如下:
(if (= a something) (if (= b otherthing) (foo))) ^ ^ notice how they line up
现在缩进的级别变得有意义了,你不再需要依靠平衡括号来获得这些信息,而且因为把它和最后的陈述放在一起更加紧凑,所以这就是Lispers所做的。 当然,这并不要求Lisp代码要这样格式化,但是这是一个相当标准的约定,人们可以依赖它。
简单的答案是,你的方式不是Lisp漂亮的打印机做的事情。 拥有一个真正的格式对代码来说总是一件好事,而pprintmacros则为你提供了这种语言的格式。
当然, 因为 pprintmacros存在,所以你不需要遵循标准的代码格式,因为人们可以通过pprint运行你的代码,并得到他们习惯的东西。 但是,由于其他人都使用pprint,或者手动逼近,所以如果不以相同的方式读取代码,就很难读取代码,而且没有简单的macros将代码转换为首选格式。
您可以使用软件包Sreafctor: Homepage重新格式化Lisp代码。
一些演示:
- 在Clojure中格式化整个缓冲区演示 。 我在一个Clojure文件上testing了10K行,花费了大约10秒的时间来格式化(显着的时间用于缩进,而不是代码重排)。
- 在Emacs Lisp中格式化整个缓冲区演示
- 在一行之间转换< – > Multiline演示
可用的命令:
-
srefactor-lisp-format-buffer
:格式化整个缓冲区 -
srefactor-lisp-format-defun
:格式化当前defun游标 -
srefactor-lisp-format-sexp
:格式化当前的sexp光标。 -
srefactor-lisp-one-line
:将当前的同一级别的sexp变成一行; 带有前缀参数,recursion地把所有内心的两性都变成一行。
格式化命令也可以在Common Lisp和Scheme上使用。
如果有任何问题,请提交问题报告,我很乐意解决。
当你有10个括号closures,它变得非常笨重。
当我用Lisp编程的时候,我在左边的括号之间留下了一个空格,在同一行上打开括号,为了简化计算,就像这样:
(如果(=某事) (如果(=其他) (foo)))
我想这些日子已经不再需要了,因为编辑们更有帮助。