Lisp代码格式

时间:2009-02-12 14:15:03

标签: lisp clojure code-formatting

其中一位花时间评论my other question关于Clojure / LISP语法的人指出,我没有用标准的LISP方式编写示例代码。所以他很友好地重写了代码片段,这是一个很大的帮助。但它在我的脑海里提出了另一个问题。为什么会这样:

(if (= a something)
  (if (= b otherthing)
    (foo)))

这是标准的LISP格式,可以使用这种形式:

(if (= a something)
  (if (= b otherthing)
    (foo)
  )
)

由于我的C ++开发背景,这就是我天真地格式化这段代码的方式。我想知道后一种格式化是否有任何好处,或者它只是一种根深蒂固的标准(如QWERTY键盘)。我不是要争论 - 我很难理解为什么第一种形式会更好。第二种形式帮助我更容易地看到代码结构。

5 个答案:

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

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