(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
示例 2
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))
)
)
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))
)
)
LISP集成开发环境会自动平衡括号并根据嵌套级别进行管理缩进。在这些情况下,示例2并没有带来任何好处。
在 C/FORTRAN/Pascal 的传统中,你更注重序列而不是嵌套(代码解析树更加扁平和宽广)。作用域的结束是您代码中更重要的事件:因此强调程度一直到某种程度上仍然很重要。
对于有经验的 Lisp 用户来说,嵌套层数比找到闭合括号更重要。将闭合括号放在自己的行中并不能真正帮助到嵌套层级。
基本思想是括号直接围绕着它们的内容。
(a)
而不是
(a
)
接下来是这样的:
(defun foo (bar)
(foo (bar (baz
...
)
...
)
...
)
)
vs.
->对比。
(defun foo (bar)
(foo (bar (baz ...) ...) ...))
在编辑Lisp文本时,基本的想法之一是,您可以通过(双击)括号或者当光标位于表达式内部或括号上时使用键盘命令来选择一个列表。然后,您可以剪切/复制该表达式,并将其粘贴到其他函数的某个位置。下一步是选择另一个函数并重新缩进该函数。完成。没有必要为闭合括号删除或引入新行。只需粘贴和重新缩进即可。它只是适合。否则,您要么浪费时间格式化代码,要么需要使用某些编辑器工具重新格式化代码(以便右括号置于独立的行上)。大多数情况下,这将创建额外的工作并阻碍移动代码。
有一种情况,有经验的Lisper会将右括号写在自己的一行中:
(defvar *persons*
(list (make-person "fred")
(make-person "jane")
(make-person "susan")
))
这里表示可以添加新人。将光标直接放在最后一行的第二个右括号之前,按下(打开新行),添加条款并缩进括号以使它们再次对齐。这样可以避免在所有括号都在同一行关闭时找到正确的括号,然后按回车键的“麻烦”。
没有必要对齐闭合括号,这在语义上并没有任何增强。大多数Lisp程序员使用像Emacs这样的好编辑器来匹配括号和关闭括号,因此使任务轻松。
在Python中,根本没有闭合括号或关键字 end ,Python程序员也可以正常工作。
使用Lisp一段时间后,你不再注意括号,因此你的示例2看起来在结尾有很多不必要的空格。更具体地说,大多数Lisp程序员使用一个能够识别括号并正确关闭表单的编辑器,因此像C语言那样需要匹配开放和关闭的括号。
至于最后一个表单应该是什么
(* n (factorial (- n 1)))
或者
(* n
(factorial (- n 1)))
这主要取决于个人喜好以及代码中发生的事情有多少(在这种情况下,我更喜欢前者,因为代码中几乎没有什么东西发生)。
((a && b) || (c && d))
替代
((a && b) || (c && d
)
)
第二种方式不是更易读吗?:)
但是,紧凑的闭合样式也适用于其他语言。
#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; }
一段时间后,你不再“看到”大括号,只能通过缩进来确定结构。if/else 语句如下:
if (cond)
{ stmt;
stmt; }
else
{ stmt; }
switch:
switch (expr)
{ case '3':
stmt;
break;
case '4':
{ stmt;
break; } }
结构体:
struct foo
{ int x;
struct bar
{ int y; };
union u
{ int a, b;
char c; }; };
除了大多数Lisp IDE使用括号匹配外,写任何合理程序所需的空间量都是荒谬的!你会因为不断滚动而得到腕管综合症。如果将所有闭合括号放在自己的一行上,1000行的程序将接近一百万行代码。这在小程序中看起来更漂亮、更易读,但这个想法在大规模应用中并不适用。
首先,第一个案例只有4行代码,而第二个案例需要7行代码。
任何了解LISP语法的文本编辑器都可以为您突出显示匹配/不匹配的括号,因此这不是问题。
我在使用CakePHP框架和它的许多嵌套array()
结构时,也遇到了同样的困境,有时达到5层以上。不久之后,我意识到过分追求括号闭合的完美只会浪费我的宝贵开发时间,并分散了我注意力。缩进是格式化中最有用的方面。
因为Lisp程序员看缩进和“形状”,而不是括号。
看起来这不是一个真正的问题,只是对Lisp的评价,但答案非常明显(但显然对于非Lisper来说并不明显!):在Lisp中,括号绝对不等同于C语言风格语言中的花括号 - 相反,它们与C语言风格语言中的括号完全相同。 Lisp程序员通常不会写
(foo bar baz
)
出于完全相同的原因,C程序员通常不会编写
foo(bar, baz
);
原因
(if foo
(bar)
(baz))
外观与之前不同
if (foo) {
bar();
} else {
baz();
}
这个问题更多与if
有关,而非括号!