Algolベースの言語が独自の行にブレースを推奨する理由の1つは、ブレースを移動することなく、区切りブレースの間に行を追加することを奨励することです。つまり、最初に
if (pred)
{
printf("yes");
}
かっこ内に別のステートメントを追加するのは簡単です。
if (pred)
{
printf("yes");
++yes_votes;
}
元のフォームが
if (pred)
{ printf("yes"); }
次に、2つのブレースを「移動」する必要がありますが、私の例では後者をより重視しています。ここでは、中括弧は、主に副作用のために呼び出される一連のステートメントとなるものを区切っています。
逆に、Lispにはステートメントがありません。すべてのフォームは expressionであり、何らかの値を生成します。まれなケース(Common Lispの場合)であっても、その値は空の(values)
フォームを介して「値なし」になるように意図的に選択されます。ネストされた式とは対照的に、式のシーケンスを見つけることはあまり一般的ではありません。「終了デリミタまで一連のステップを開く」という欲求はそれほど頻繁には発生しません。なぜなら、ステートメントがなくなり、戻り値がより一般的な通貨になるにつれて、式の戻り値を無視することがより少なくなるためです。副作用だけで一連の式を評価することはまれです。
Common Lispでは、progn
フォームは例外です(兄弟も同様です):
(progn
(exp-ignored-return-1)
(exp-ignored-return-2)
(exp-taken-return))
ここでprogn
は、3つの式を順番に評価しますが、最初の2つの戻り値は破棄します。最後の閉じ括弧を独自の行に書くことを想像できますが、ここでは最後の形式が特別であるため(ただし、特別であるというCommon Lispの意味ではない)、明確な扱いで、新しいものを追加する可能性が高いことに注意してください呼び出し側は新しい副作用だけでなく、戻り値の変更の影響を受けるため、「最後に別の式を追加する」のではなく、シーケンスの途中の式。
大幅に単純化すると、Lispプログラムの大部分の括弧は、Cに似た言語のように関数に渡される引数の区切りであり、ステートメントブロックの区切りではありません。同じ理由で、Cの関数呼び出しを囲む括弧を引数の近くに保持する傾向があるため、Lispでも同じことを行い、その密接なグループ化から逸脱する動機は少なくなります。
括弧を閉じることは、括弧を開くフォームのインデントよりもはるかに重要ではありません。やがて、括弧を無視し、形状ごとに読み書きすることを学びます。これは、Pythonプログラマーが行うのと同じです。ただし、その類推から、括弧を完全に削除する価値があると思わせないでください。いいえ、これはのために保存された議論ですcomp.lang.lisp
。