web-dev-qa-db-ja.com

言語がブロックの明示的なマーカーよりもインデントを好むのはなぜですか?

私はHaskellを学んでいて、自動インデントツールを探していました。私はあまり見ていませんでしたが、Haskellでは(Pythonのように)インデントがブロックを意味することを学びました。その結果、Cファミリーの他の言語と同じくらい強力な、{}(中括弧)やbeginendキーワードなどの明示的なマーカーを使用する自動フォーマットツールを作成することは不可能だと思います。

読みやすさのためにインデントを強制する言語は気にしませんが、インデントを強制することといくつかの明示的なマーカーを持つことの両方の利点を理解できません。そのため、自動化ツールは、どのブロックに何が属しているかを理解できます。

ブロックをインデントするマークの設定がそのコードlooksより良い場合、私はまだ利点を理解していません。タブとスペースが異なるエディターや異なるフォント(たとえば、見栄えのよいモノスペースフォント)で異なる方法で表現される場合、プログラマーがコードをきちんと提示することを期待することは不可能です。現在のテキストエディターを考慮できるツールは、コードを正しくフォーマットするのにはるかに適しています。

言語デザイナーが明示的なブロックマーカーよりもインデントを選択するのはなぜですか?

11

グイドフォンロッサム

Guido Van Rossumへのインタビュー から、フルテキストで見ることができます with books.google.com (鉱山を強調):

グループ化のインデントの選択は、Pythonの新しい概念ではありませんでした。 これをABCから継承しましたですが、古い言語のoccamでも発生しました。 ABCの作者がoccamからアイデアを得たのか、独自に発明したのか、あるいは共通の祖先がいたのかはわかりません。もちろん、他の分野で行ったように(たとえば、ABCは言語のキーワードとプロシージャ名に大文字を使用し、私がコピーしなかったアイデア)、[好きになった機能 ABCを使用している間はかなりCの間で一般的な特定の種類の無意味な議論を排除するように見えたため当時のユーザー、約巻き毛を配置する場所中括弧

フォンロッサムは [〜#〜] abc [〜#〜] からひらめきを得て、すべてをコピーする必要はなかったにもかかわらず、インデントの使用は、宗教戦争を避ける。

読み取り可能なコードはとにかく自発的にインデントを使用しますでグループ化を示し、-インデントが構文的なグループ化と一致しないコードで微妙なバグに遭遇しました中括弧の使用-プログラマーとレビュアーは、インデントがグループと一致していると想定していたため、バグに気づきませんでした。繰り返しますが、長いデバッグセッションは貴重な教訓を教えてくれました。

Rossumはまた、グループ化とインデントの不一致によるバグを目撃しましたが、どうやらコードを構造化するためだけにインデントに依存する方がプログラミングエラーからより安全になるでしょう。1

ドナルドE.クヌース&ピーターJ.ランディン

言及されたインタビューで、Guidoはインデントを使用するDon Knuthのアイデアに言及しています。詳細は The Knuth Indentation Quote rediscovered を引用して gotoステートメントによる構造化プログラミング を引用しています。 Knuthは、Peter John Landinの 次の700プログラミング言語 も参照しています(インデントについては、ディスカッションセクションを参照してください)。 Landinの設計 [〜#〜] iswim [〜#〜] これは、開始/終了ブロックではなく、インデント付きの最初の言語のように見えます。それらの論文は、実際の議論よりも、プログラムを構造化するためにインデントを使用することの実現可能性についてです。


1。これは、プログラミングから捕捉して回復するために、実際にはグループ化構成と自動フォーマットの両方を持つことの好意の議論だと思いますエラーが発生します。 Pythonでインデントを台無しにした場合、コードをデバッグする人はどちらが正しいかを推測する必要があります。

if (test(x)):
  foo(x)
  bar(x)

barを常に呼び出すか、テストが成功した場合にのみ呼び出しますか?

グループ化構造は、コードを自動インデントするときに間違いを見つけるのに役立つ冗長性のレベルを追加します。 Cでは、同等のコードを次のように自動インデントできます。

if (test(x))
  foo(x);
bar(x);

barfooと同じレベルにすることを意図した場合、コード構造に基づく自動インデントにより、foobarの前後に中括弧を追加することで修正できる問題があることがわかりました。

Python:インデントに関する神話 には、Cからのおそらく悪い例があります:

/*  Warning:  bogus C code!  */

if (some condition)
        if (another condition)
                do_something(fancy);
else
        this_sucks(badluck);

これは上記と同じです。Emacsでは、ブロック/関数全体を強調表示し、Tabキーを押すと、すべてのコードがインデントされます。人間のインデントとコード構造の不一致は、何かが間違っていることを示しています(それとその前のコメント!)。

その上、Cでインデントがオフになっている中間コードは、単にmasterブランチを通過しないので、すべてのスタイルチェックにより、GCC/Jenkinsが私に悲鳴をあげるでしょう。私は最近、Pythonで上記の問題と同様の問題を抱えていました。1レベルのインデントでステートメントがオフになっています。 Cに閉じ括弧を超えるコードがある場合がありますが、Tabキーを押すと、コードが「間違って」インデントされます。これは、バグを確認するためのもう1つのチャンスです。

13
coredump

これは非常に主観的であり、多くの炎上戦争の原因です。しかしながら:

シンボルを区切るブロックがあるandインデントは、DRY principleに違反します。 2つの異なる方法で情報を自動化します。自動インデントツールの存在は症状このDRY違反です。インデントを自動的に生成できるということは、冗長な情報であることを示しています。インデントと記号mayが同期されず、誤解を招くコードにつながります。

Python Design and History FAQ はこれを非常に明確に述べています:

Pythonステートメントのグループ化にインデントを使用するのはなぜですか?

Guido van Rossumは、グループ化にインデントを使用することは非常にエレガントであり、平均Pythonプログラムの明確性に大きく貢献していると信じています。ほとんどの人はしばらくしてこの機能を気に入って学習します。

開始/終了の括弧がないので、パーサーと人間のリーダーによって認識されるグループ化の間に不一致はありません。

Pythonの自動インデントツールを作成できないことは事実ですが、これは良いことです。つまり、自動化ツールで調整する必要がある構文に冗長性がないということです。

タブとスペースはPythonの正当な問題であり、同じコードベースでタブとスペース(インデント用)を混在させないことをお勧めします。

Pythonは(現在は廃止された)先行言語ABCから重要なインデントを継承しています。 ABCはユーザビリティテストを使用して設計を指示した数少ないプログラミング言語の1つです。したがって、構文についての議論は通常主観的な意見や個人的な好みに帰着しますが、重要なインデントの選択は実際にはより確かな基盤を持っています。

7
JacquesB

言語デザイナーは、セミコロンと中括弧がコードの読み取り時にノイズを追加し、生産性を損なうと信じている(または少なくとも潜在的なユーザーが信じていると考える)ため、構文的に重要な空白を選択します。もう1つの一般的な理由は、悪い/一貫性のないコーディングスタイルが読みやすさを損なうことです。一般的なインデントスキームを強制することにより、言語全体の読みやすさが向上します。その後者の理由は、自動フォーマットのIDEがより一般的ですが、今でも重要ではなくなっています。

2
Telastyn