プログラミング言語は厳格か緩いか?[閉まっている]


14

PythonおよびJavaScriptでは、セミコロンはオプションです。

PHPでは、配列キーを囲む引用符はオプション($_GET[key]vs $_GET['key'])です。ただし、それらを省略すると、最初にその名前の定数が検索されます。また、ブロックに2つの異なるスタイル(コロン、または括弧で区切られた)を使用できます。

現在、プログラミング言語を作成していますが、どの程度厳密に作成するかを決定しようとしています。余分な文字は本当に必要ではなく、優先順位のために明確に解釈できる場合が多くありますが、一貫性を促進するためにそれらを強制するべきかどうか疑問に思っています。

どう思いますか?


さて、私の言語はプログラミング言語というよりも、凝ったテンプレート言語ではありません。Haml テンプレートDjangoテンプレートの一種です。私のC#Webフレームワークで使用されることを意図しており、非常に拡張可能であることになっています。


22
これは聖戦のトピックです。

1
Pythonistasはセミコロンの使用を推奨していません。率直に言って、それらが必要かどうかはわかりません。1行に複数のステートメントを許可するだけで、苦労せずに完全に回避できます。だから...私はより厳しい言語に賛成です。ただし、StyleCopなどのコード分析ツールを使用して、言語の外で物事を実施できる場合があります。
ジョブ

1
PHP配列キーの引用符はオプションではありません。それらはPHP2にありましたが、それ以降のバージョンでは定数を自動定義しました。ただし、基本的な文字列補間では使用できません"..$_GET[raw].."
マリオ

1
@Ralph:ルールはもう少し複雑です。書くのは正しい"xx$_GET[raw]xx"-中括弧を使い始める場合は、キー"xx{$_GET['raw']}xx"を引用符で囲む必要があります。中括弧が使用されている場合、通常のPHPパーサーがそれをチェックし、厳格な構文が適用されます。"$_GET[x]"キーが生の文字列として扱われるためだけであり、それも厳密なルールであり、PHPはでエラーを解析します"$_GET['x']"
マリオ

2
@マリオ:私たちがこの会話をしているという事実は、配列キーの処理方法にあいまいさと混乱があることを意味します。文字列の中にあるように見えますが、あいまいではありませんが一貫性がありません(中括弧を使用しない限り、すでに文字列の中にある場合は引用符を使用できません。そして、「通常の」PHPの外の文字列...まあ、それはそのような奇妙なくだらないことをします。
mpen

回答:


19

言語の種類によって用途が異なるため、この質問に対する答えは、実際に何に使用するかによって異なります。

たとえば、Perlは非常にルーズな言語であり、簡単な修正や数値計算スクリプトを書くのに非常に便利です。堅牢なプロジェクトには、C#を使用します。

ターゲットの使用に適したバランスを取る必要があります。厳密であればあるほど、コードの記述に費やす時間が長くなりますが、堅牢性、再利用性、および保守が容易になります。


26

プログラミング言語で(スクリプト言語とは対照的に)探しているのは、一貫性と強力な型指定です。

現在のプログラミング言語では、曖昧になることなく、たとえば特定の場所でセミコロンを省略できます({}ブロックの最後の式は1です)。これらの場合にプログラミング言語で文字を省略することができる場合、プログラマーには余分な問題があります。一般的な言語構文に加えて、彼女は現在、どの場合に構文の一部も省略できるかを知っている必要があります。

この余分な知識は、コードを記述するプログラマーにとっては問題ありませんが、後から既存のコードを解釈しなければならない人にとっては負担になります(しばらくして元の作者を含む)。

PHPの例keyでは、同じコンテキストで定数が追加されると、プログラムにわずかなバグが生じる可能性があります。コンパイラは、それが意図したものではないことを知る方法がないため、問題はコンパイル時ではなく実行時にのみ明らかになります。


1
あなたはdeveloppersの可能性を制限する必要があり、同意する:もっとpossibilites =>実際の作業を行うに多くの(私はこの方法またはそのように進めるべき)=>短い時間を考える必要性
Kemoda

暗黙的な型キャストの欠如が言語の構文にどのように関係しているかはわかりません。
dan_waterworth

5
また、あなたが読んだ$_GET[key]とき何も知らない key定数かどうかを知るためだけに、プロジェクト全体をgrepすることになります。このようなことにより、0.5秒の書き込みが節約され、読み取りに20秒かかります。
モシェレバ

言語が区別なくオプションを提供する場合、コーディングスタイル-コード化されているかどうかに関係なく、そのうちの1つを標準化する傾向があります
...-Deduplicator

11

曖昧さが存在するすべての場所で、コンパイラはプログラマが実際に何を意味していたかを推測する何らかの方法を持っている必要があります。これが起こるたびに、プログラマーが本当に何か違うことを意味する可能性がありますが、あいまいさの解決規則はありませんでした。

論理的に正しいコードを書くことは、すでに十分に困難です。構文上のあいまいさを追加することは、表面的には「友好的」に思えるかもしれませんが、コードベースに新しい、予期しない、デバッグが困難なバグを導入することを歓迎します。結論として、できるだけ厳しくしてください。

あなたの例から、セミコロンはPythonとJavaScriptではオプションであると述べました。少なくともJavascriptの場合、これは完全に真実ではありません。セミコロンは、他のCファミリー言語と同様にJSでも必要です。ただし、特定の状況下で欠落しているセミコロンを挿入するには、言語仕様でJavaScriptパーサーが必要です。これは、意図を誤ってコードを台無しにする傾向があるため、非常に悪いことと広く見なされています。


6

あなたの言語をどれほどゆるくするべきかに対する答えは、テキサスのアクセントで言われた質問の答えと同じです。


わかりません。
mpen

4
冗談での私の悪い試みは、特に経験の浅い開発者をミックスに追加するとき、システムがますます大きくなるにつれて動的型付けがあなたを噛むかもしれないということでした。私の経験では、価値のあるシステムはどんどん大きくなる傾向があり、開発者の数も増えています。その場合、「シンボルのすべての使用法を見つける」または「すべての名前を変更する」または「安全な削除」または「ソリューションのエラーを見つける」ことは、非常に貴重です。VBが遅延バインディングであり、大規模な型強制を行うという限られた意味での動的型付けは、現在のギグで多くのバグを引き起こしています。
ヘンリック

エルゴ、もしあなたがあなたのプロジェクトについて幸運だと感じたら、例えば、良い経験豊富な開発者がいる幸運だとか、正しいコードを書くという点で幸運だと。動的型付けを使用できます。
ヘンリック

2
ああ...しかし、この質問は決して動的なタイピングに関するものではありませんでした:)
mpen

1
ああ、非常に本当のRaplh。動的言語は、通常はより緩やかであるため、より緩やかであると考える傾向があります。あなたは正しいです。
ヘンリック

4

言語のバリエーションがそれほど多くなければ、コーディングの一貫性のために誰もが一生懸命働く必要はありません。ユーザーが複雑さを不必要に増加させる要求をするとき、私たちはそれを好まないので、なぜ私たちの開発言語のそれを尋ねるべきですか?


+1:まったく同感です。KISSやYAGNIのような原則が言語設計に適用されない理由はわかりません。
ジョルジオ

2

私の個人的な好みは、タイプミスをキャッチするのに十分な厳格さを持ちながら、できるだけ余分な定型文を持たないことです。この問題については、http://www.perlmonks.org/?node_id = 755790で説明しています

とは言っても、あなたは自分で言語を設計しているのです。あなたはそれをあなたが望むものにすべきです。


+1:...タイプミスをキャッチするのに十分な厳密さを備えているが、余分なボイラープレートをできるだけ少なくする能力。- はい。Anders HejlsbergのC#の計画に精通していますか?彼は「式より本質」を強調するために意識的な決定をしています。channel9.msdn.com/Blogs/matthijs/...
ジム・G.

@ jim-g:考えてくれてありがとう。私はC#について何もよく知らない。私は長年にわたってマイクロソフトの世界で働いていません。
btilly

1

私の言語が私が意味することをするのが好きです。一般的に、それはゆるいことにかなり傾いています。また、要素またはブロックに「strict」というタグを付けて、その限られた領域をデバッグ/分析できるようにしたいと思います。


1

私は一般的に「プログラマーとしての私にとってそれが容易になるのは何か」という側面に陥る傾向があります。もちろん、それは複数のことを意味します。Javascriptには型チェックはほとんどありません。これは、奇妙なバグに遭遇するまでうまく機能します。一方、Haskellには多くの型チェックがあり、より多くの作業を事前に行いますが、いくつかのクラスのバグを覆い隠します。

正直に言うと、私は多くの言語をチェックしてそれらが何をするかを確認し、それらのどれも当てはまらないニッチを見つけようとします!

私はそれを行うための明白な正しい方法があるとは思わない、あるいは少なくとも人々がコンセンサスをまだ見つけていない場合はそうではない。したがって、異なる型システムで言語を作成することにより、学習しています。

幸運を。


1

優れたプログラミング言語には厳格なルールが必要であり、その実装は一貫して実施されることが期待されますが、ルールは役に立つように書かれている必要があります。さらに、2つの実質的に異なるプログラム間の「ハミング距離」が1つに過ぎない場合を避けるために、言語の設計を検討することをお勧めします。明らかに、数値リテラルまたは文字列リテラルではそのようなことを達成することはできません(123を意味するプログラマーが1223または13とタイプする場合、コンパイラーはプログラムが何を意味するかをあまりよく理解できません)。一方、言語が:=割り当てと==等価比較に使用され、単一の= 何らかの法的目的のために、比較であるはずの偶発的な割り当てと、割り当てであるはずの偶発的な何もしない比較の両方の可能性を大幅に減らします。

コンパイラーが物事を推測するのに役立つ場所はありますが、そのような推論は多くの場合、最も単純な場合に最も価値があり、より複雑な場合にはあまり価値がないことをお勧めします。たとえば、次の置換を許可します。

  辞書<complicatedType1、complicatedType2> item =
    新しい辞書<complicatedType1、complicatedType2()>;

  var item = new Dictionary <complicatedType1、complexType2()>;

複雑な型推論は必要ありませんが、コードを非常に読みやすくします(特に、必要なシナリオでのみ、より冗長な構文を使用します。たとえば、保存場所の型が式の型と正確に一致しないためです)それを作成すると、それを必要とする可能性のある場所に特別な注意を喚起するのに役立ちます)。

より洗練された型推論を試みることの1つの大きな困難は、あいまいな状況が発生する可能性があることです。良い言語は、プログラマーがそのようなあいまいさを解決するために使用できる情報をコンパイラーに含めることを許可することをお勧めします(たとえば、一部のタイプキャストを他のタイプキャストよりも望ましいと見なすことによって)オーバーロードは異なるコードを実行する可能性があり、プログラマーは、どちらかを使用できる場合に同じように動作する必要があることを示しているか、上記のいずれの方法でも処理できないもの(およびそれらのみ)にフラグを立てます。


1

私にとって、読みやすさが最も重要です。

この言語を経験した人にとっては、コードフラグメントの意味は、コンテキストを深く分析する必要なく明確でなければなりません。

言語は、できるだけ頻繁に間違いにフラグを立てることができなければなりません。すべてのランダムな文字列が構文的に正しいプログラムを作成する場合、それは役に立ちません。変数は自動的にそれらが使用されている最初の時間を作成している場合と、その後、誤った綴りclientとしては、cleintあなたのコンパイルエラーを与えることはありません。

構文に加えて、言語には明確に定義されたセマンティクスが必要であり、まともな構文を決定するよりもさらに難しいかもしれません...

良い例:

  • Javaでは"1"、文字列、1int、1.0double、および1Llongです。一見すると、それが何であるかがわかります。

  • Javaでは=、割り当てです。プリミティブ型の値と参照型の参照を割り当てます。複雑なデータをコピーしたり比較したりすることはありません。

  • Javaでは、メソッドの呼び出しには括弧が必要であり、この方法は変数とは明確に区別されます。したがって、括弧がなければ、メソッド定義を検索する必要はなく、データを読み取るだけです。

悪い例:

  • Javaのようなシンボルはclient、パッケージパス要素、クラスまたはインターフェイス名、内部クラス名、フィールド名、メソッド名、ローカル変数など、ほぼすべてのものです。命名規則を導入するか従うかはユーザー次第です。

  • Javaでは、ドット.は使いすぎです。パッケージ名内のセパレーター、パッケージとクラス間のセパレーター、外部クラスと内部クラス間のセパレーター、インスタンス式とインスタンスで呼び出されるメソッド間のコネクターなどがあります。

  • 多くの言語では、ifブロックの中括弧はオプションであり、誰かが(実際には存在しない)ブロックにステートメントをもう1つ追加すると、厄介な間違いにつながります。

  • 中置演算子:数値式に立ち止まって、それが何を意味するのかを一歩一歩慎重に考えなければならない場合があります。私たちは皆、のような中置記法で数式を書くのに慣れていますa * b / c * d + e。ほとんどの場合、加算と減算よりも乗算と除算の優先順位を覚えています(ただしc*d、除算ではなく、除算のみでc乗算することに気づきましたdか?)。しかし、独自の優先順位ルールといくつかの言語のオーバーロードを伴う追加の挿入演算子が非常に多くあるため、追跡するのは困難です。括弧の使用を強制する方がより良いアプローチだったかもしれません...


あなたはほとんど曖昧さについて話しましたが、曖昧さを作成せずに同じことをする複数の方法があります。たぶん、2つの乗算演算子と*を持つことができます×。両方5*3と5×3`は同じことを意味し、経験豊富なプログラマーは、周囲のコンテキストを見て回ることなく、それらが何を意味するかを正確に知っています。ただし、問題は同じことを行う2つの方法があり、プログラム全体で誰かがそれらの間で交換する可能性があることです。質問をしたとき、これが私がもっと心配していたことだと思います。
mpen

-2

自然言語との類推を検討することもできます。メールで、あなたは文法ナチですか?または、不定詞の分割、接続詞の欠落、修飾語の置き忘れなど、いくつかの文法エラーで大丈夫ですか。答えは、個人的な好みに要約されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.