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)))

我想这些日子已经不再需要了,因为编辑们更有帮助。