如何有效地读写Lisp代码?

时间:2014-05-29 06:09:08

标签: lisp common-lisp readability code-readability

我目前正在学习Lisp,我认为我掌握了基础知识(我使用了优秀的书 Land of Lisp ,到目前为止我已经阅读过了并且工作了大约四分之一。)

我尝试根据我已经学到的东西创建自己的Lisp程序。不知何故,它的工作原理。但它只是以某种方式。到目前为止,我一直在开发主要使用C语言的语言,例如C#和JavaScript(请注意,我完全清楚JavaScript不是基于C语言)。

尽管如此,我过去常常认为"在C语法中,当我用C#或JavaScript编写代码时,我可以用一种非常简单的方式写下来。相比之下,在编写Lisp代码时,我很难将所有这些括号包围起来。

如果我有一个简单的陈述,例如

(setf x (+ 2 3))

我总是发现自己试图从左到右阅读它,发现它不起作用,然后搜索最里面的一对括号,然后从里到外进行处理。对于这个简单的表达式,这非常快。

但是如果我有更复杂的代码(虽然它根本不复杂),比如使用let的函数,那么找到最里面的一对(我至少对我来说)更难括号:

(defun foo ()
  (let ((x 23)
        (y 42))
  (+ x y)))

这里已经有点难以看出在什么后发生了什么,以及什么是嵌套到什么。现在添加一些cond内容,或许可以结合几个lambda,我完全迷失了,发现自己数了几分钟(字面意思)括号。

写作时也是如此,我对括号的数量感到迷茫,我不认为我甚至看到过#34;复杂的" Lisp代码。

随着时间的推移会变得更好吗?即,你习惯了吗?或者,有没有关于如何处理读取和编写Lisp代码以使事情变得更容易的技巧?经验丰富的Lisp程序员如何做到这一点?任何提示?

2 个答案:

答案 0 :(得分:10)

您需要正确缩进。你的例子不是。

(defun foo ()
  (let ((x 23)
        (y 42))
  (+ x y)))

下面:

(defun foo ()
  (let ((x 23)
        (y 42))
    (+ x y)))

最后一个表达式需要向右移动。然后你可以看到它在LET内。

Lisp有一些结构模式。不是很多。一旦你学习和训练这些,阅读Lisp相对容易。比学习中文的难度要小得多。

一些模式:

(symbol ...)

符号给出锚点

((a 10) (b 20))

绑定列表,例如LET

(with-foo (foo :option1 1 :option2 2)
  (body))

WITH-OPEN-FILE这样的宏。

然后是复杂的函数arglist本身。位置参数,可选参数,关键字参数。 &rest&aux

还有一些,但不是太多。一旦学会了基本的宏和特殊表单模式,代码阅读就变得容易了。

如何改进?阅读代码。培养。这并不难。有点像骑自行车。第一天似乎很难,然后它是自动化的。

<强>书写。

要编写代码,您需要一个可以缩进的编辑器。大多数只能缩进行,但不能格式化整个表达式。因此,您需要进行格式化。有一些基本规则。 Lisp有一台漂亮的打印机,可以格式化。但这通常在编辑器中无法使用,而且它不知道评论等内容。

当我编写一段Lisp代码时,我通常会花一些时间来正确编写代码。

  • 行太长了?
  • 悬空括号?
  • 正确的结构?
  • 路线?
  • 足够的视觉线索?
  • 命名?
  • 评论?
  • 文档?

答案 1 :(得分:4)

我也是Lisp的新手。但是,我觉得它相对容易学习。

IMO要记住的主要事情是Lisp是抽象语法树的直接表示。如果其他语言是面向文本的,并且它们的语法被建模为更接近人类语言,那么Lisp是面向树的。因此,它需要一种完全不同的阅读和写作方式。如果您正在计算括号,那么您做错了。

您应该学会将lisp代码作为树来阅读。使用正确的压头,它将自动表示为这样,s表达式的第一个标记表示任何子树的根。因此,布局类似于树视图中的布局,例如, Windows资源管理器中的左侧。

也许这对我来说更容易,因为我编写了直接使用C / C ++代码的AST的分析软件。我记得那时从了解源代码到理解AST的步骤并不容易,我一直犯错误,如果我考虑过AST,我可以避免这种错误,而不是总是考虑源代码。

出于这个原因,我推荐ParEdit用于编写代码的emacs。 ParEdit阻止你编写Lisp代码作为文本,而是允许(或强制,但你想调用它)你直接编写和转换AST。