43 lisp coding-style
为什么Lispers会像样本1中所示那样格式化代码,而不是样本2中所示?对我来说(我想,对于大多数来自不同编程背景而不是Lisp的人),样本2中显示的格式将更容易阅读.Lispers是否更喜欢样本1样式?
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
Run Code Online (Sandbox Code Playgroud)
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))
)
)
Run Code Online (Sandbox Code Playgroud)
Pon*_*gge 33
LISP IDE环境倾向于自动平衡括号并根据嵌套级别管理缩进.样本2在这些情况下没有任何优势.
在C/FORTRAN/Pascal遗产中,您倾向于强调对嵌套的排序(代码解析树更浅更宽).范围的结束是您的代码中更重要的事件:因此重点已经并且在某种程度上仍然更为重要.
Rai*_*wig 21
对于有经验的Lisp用户,嵌套级别比查找右括号更重要.将右括号放在自己的行上对嵌套级别没有帮助.
基本思想是括号直接围绕其内容.
(a)
Run Code Online (Sandbox Code Playgroud)
并不是
(a
)
Run Code Online (Sandbox Code Playgroud)
以下是:
(defun foo (bar)
(foo (bar (baz
...
)
...
)
...
)
)
Run Code Online (Sandbox Code Playgroud)
与
(defun foo (bar)
(foo (bar (baz ...) ...) ...))
Run Code Online (Sandbox Code Playgroud)
编辑Lisp文本时的一个基本思想是,您可以通过(双击)括号来选择列表(或者当光标位于表达式内或括号中时使用键命令).然后,您可以剪切/复制表达式并将其粘贴到其他函数中的另一个位置.下一步是选择其他功能并重新缩进功能.完成.没有必要删除或引入用于结束括号的新行.只需粘贴并重新缩进.它只是适合.否则你会浪费时间格式化代码,或者你需要用一些编辑器工具重新格式化代码(以便关闭括号是在他们自己的行上.大多数时候它会创建额外的工作并阻碍移动代码.
有一次,经验丰富的Lispers有时会在自己的行上写下结束括号:
(defvar *persons*
(list (make-person "fred")
(make-person "jane")
(make-person "susan")
))
Run Code Online (Sandbox Code Playgroud)
这表明可以添加新人.将光标直接放在最后一行的第二个右括号之前,按下co(空行),添加该子句并缩进它们再次对齐的括号.这样可以省去找到正确括号的"麻烦",然后在所有括号在一行上关闭时按回车键.
Eli*_*sky 15
因为没有必要排队关闭parens.它不会在语义上添加任何内容.要知道要关闭多少,大多数Lispers使用一个好的编辑器,比如Emacs,它将parens与关闭parens相匹配,因此使任务变得微不足道.
在Python中,根本没有关闭的parens或end
关键字,Pythonistas也很好.
使用Lisp一段时间之后,你不再注意到括号了,所以你的例子两个在它的末尾有一堆不必要的空格.更具体地说,大多数lispers使用一个知道括号的编辑器并负责正确关闭表单,因此您作为开发人员不需要像在例如C中那样匹配开括号和右括号.
至于最后的表格是否应该是
(* n (factorial (- n 1)))
Run Code Online (Sandbox Code Playgroud)
要么
(* n
(factorial (- n 1)))
Run Code Online (Sandbox Code Playgroud)
这主要取决于个人偏好以及代码中发生了多少事情(在这种情况下,我更喜欢前者,因为代码中发生的事情很少).
第一个也是显而易见的原因:第一种情况下有 4 个 LOC,而第二种情况下有 7 个 LOC。
任何了解 LISP 语法的文本编辑器都会突出显示匹配/不匹配的括号,所以这不是问题。
除了大多数Lisp IDE使用paren匹配的事实,你用来编写任何合理程序的空间量都是荒谬的!你会得到所有滚动的腕管.如果将所有右括号放在自己的行上,那么1,000行程序将接近一百万行代码.它可能看起来更漂亮,更容易在一个小程序中阅读,但这个想法根本不会很好地扩展.
为什么C程序员写的东西如下:
((a && b) || (c && d))
Run Code Online (Sandbox Code Playgroud)
代替
((a && b) || (c && d
)
)
Run Code Online (Sandbox Code Playgroud)
#2不会更容易阅读吗?:)
但是,严肃地说,成熟的结束风格也适用于其他语言.
#include <stdlib.h>
#include <stdio.h>
int main(void)
{ int i, j, k;
for (i = 0; i < 1000; i++)
{ for (j = 0; j < 1000; j++)
{ for (k = 0; k < 1000; k++)
{ if (i * i + j * j == k * k)
{ printf("%d, %d, %d\n", i, j, k); } } } }
return 0; }
Run Code Online (Sandbox Code Playgroud)
过了一会儿,你不会"看到"牙箍,只是缩进给出的结构.if/else看起来像这样:
if (cond)
{ stmt;
stmt; }
else
{ stmt; }
Run Code Online (Sandbox Code Playgroud)
开关:
switch (expr)
{ case '3':
stmt;
break;
case '4':
{ stmt;
break; } }
Run Code Online (Sandbox Code Playgroud)
结构:
struct foo
{ int x;
struct bar
{ int y; };
union u
{ int a, b;
char c; }; };
Run Code Online (Sandbox Code Playgroud)