web-dev-qa-db-ja.com

識別子にスペースを許可するのはプログラミング言語にとって悪い設計ですか?

一部の( リンク1リンク2 )プログラミング言語では、識別子(変数、プロシージャなど)はありませんが、ほとんどは使用せず、プログラマは通常 キャメルケースを使用しますcase および名前の単語を区切るその他の方法。

スペースやその他のUnicode文字をサポートするために、一部のプログラミング言語では、名前の開始と終了を区切る特定の文字で名前をカプセル化できます。

スペースを許可することは悪い考えですか、それとも歴史的な理由で許可されていないのですか(現在よりも多くの制限があった場合、または単に実装する価値がないと判断された場合)。

問題は、新しく作成されたプログラミング言語でそれを実装することの主な長所と短所についてです。

関連ページ: リンク1リンク2 .

51
user7393973

以下を検討してください。

 var [Example Number] = 5;
 [Example Number] = [Example Number] + 5;
 print([Example Number]);

 int[] [Examples Array] = new int[25];
 [Examples Array][[Example Number]] = [Example Number]

より伝統的な例と比較してください:

 var ExampleNumber = 5;
 ExampleNumber = ExampleNumber + 5;
 print(ExampleNumber);

 int[] ExamplesArray = new int[25];
 ExamplesArray[ExampleNumber] = ExampleNumber;

脳が2番目の例を読む負担がはるかに低いことに気付いたと思います。

識別子に空白を許可する場合は、Wordの開始と停止をマークするために他の言語要素を配置する必要があります。これらの区切り文字は、脳に余分な解析を強制し、どれを選択するかに応じて、人間の脳にまったく新しい曖昧性の問題のセットを作成します。

区切り文字を入れず、コンテキストのみでコードを入力するときに、どの識別子について話しているのかを推測しようとする場合は、別の種類のワームの缶を招待します。

 var Example = 5;
 var Number = 10;
 var Example Number = Example + Number;

 int[] Examples Array = new int[25];
 Examples Array[Example Number] = Example Number;

 Example Number = Example Number + Example + Number;
 print text(Example Number);

完全に実行可能です。

あなたの脳のパターンマッチングのための総痛み。

これらの例は、私が選んでいる単語の選択のためだけでなく、あなたの脳が何を特定するためにいくらか余分な時間を費やすため、読むのは大変ですすべての識別子です。

もう一度、より規則的な形式を考えてみましょう。

 var Example = 5;
 var Number = 10;
 var ExampleNumber = Example + Number;

 int[] ExamplesArray = new int[25];
 ExamplesArray[ExampleNumber] = ExampleNumber;

 ExampleNumber = ExampleNumber + Example + Number;
 printText(ExampleNumber);

何か気づきましたか?

変数の名前はまだひどいですが、それを読むための負担は非常に少なくなりました。これは、すべての単語の始まりと終わりを識別するための自然なアンカーが脳にあり、思考のその部分を抽象化できるためです。あなたはもうそのコンテキストについて心配する必要はありません-あなたはテキストの切れ目を見るでしょう、あなたはそれが新しい識別子であることを知っています。

コードを読むとき、あなたの脳は単語をそれほどreadしないmatchesそれはあなたが今あなたの心の中に持っているもので。あなたは「ExampleWord」を読むことを本当に止めません。モノの全体的な形、ExxxxxxWxxdが、メンタルヒープに隠しておいたものと一致します。そのため、 "ExampleWord = ExapmleWord"などの間違いを見逃しがちです。脳は実際にそれを読んでいません。あなたはちょうど同じようなものを一致させています。

もう一度、以下を検討してください。

 Example Word += Example  Word + 1;

そのコードをデバッグしようとしている自分を想像してみてください。 「例の単語」の余分なスペースを何回見逃すか想像してみてください。見当違いの文字は、一見してフォークを検出するのがすでに困難です。余分なスペースは、桁違いに悪くなります。

結局、空白を許可するとテキストmoreが読みやすくなるとは言いがたい。余計なターミネーターを追加したり、頭脳に余分なオーバーヘッドがかかったりして、この種の機能を使用する価値があると私が信じているのは難しいと思います。

個人的には、私はそれを悪いデザインだと思っています-コンパイラ、インタプリタなどの面倒のためではなく、私の頭脳がそれらのスペースをつまずいて、それはまだ始まっていないのに、これから始まる新しい識別子です。

ある意味で、脳は 分岐予測 になると、プロセッサーと同じ問題を抱えています。

ですから、どうぞ私たちの考えに親切にしてください。識別子に空白を入れないでください。

101
T. Sar

識別子にスペースを許可するのはプログラミング言語にとって悪い設計ですか?

短い答え:

多分。

少し長い答え:

設計とは、複雑な問題に対する競合する解決策を特定して重み付けし、利害関係者のニーズを満たす適切な妥協を行うプロセスです。 それらの利害関係者の目標の文脈でを除いて、「悪いデザイン」や「良いデザイン」はありません。そして、それらの目標が何であるかを述べていないため、質問は曖昧すぎて答えることができません。

さらに長い答え:

上記で触れたように、言語デザイナーが取り組んでいる支持者の目標に依存します。私がよく知っている2つの言語について考えてみましょう。人間が読める形式のMSIL、C#がコンパイルする低レベルの「中間言語」、およびC#です。

C#は、Microsoftが戦略的に重要であると考える環境で、基幹業務開発者の生産性を高める言語になることを目的としています。 C#では、identifierは1つ以上のUTF-16文字のシーケンスであり、すべての文字は英数字または_として分類され、最初の文字は数字ではありません。

この字句文法は、戦略的に重要なLOB開発者のニーズに一致する特性を持つように慎重に選択されました。

  • 識別子として明確にレキシブルです。たとえば1e10は、語彙的にdoubleであいまいであるため、正当な識別子であってはなりません。
  • プライベートフィールド_fooの命名など、C、C++、およびJavaで一般的に使用されるイディオムをサポートしています。 C#は、共通のLOB言語を既に知っている開発者にアピールするように設計されています。
  • ほとんどすべての人間の言語で書かれた識別子をサポートしています。 C#でvar φωτογραφία = @"C:\Photos";を記述したい場合は、先に進んでください。これにより、英語を母国語としない開発者が言語にアクセスしやすくなります。

ただし、C#は識別子のスペースをサポートしていません。

  • 語彙の文法が複雑になり、あいまいさが生じるため、解決する必要があります。
  • 相互運用状況の大部分では、これは必要ありません。パブリックメンバーにスペースを入れるように名前を付ける人は誰もいません。

C#識別子では、文字と数字以外の文字を許可しないことをお勧めします。

対照的に、MSILでは、メソッド名にスペースやその他の「奇妙な」文字を含めることを含め、ほとんどすべての関数に名前を付けることができます。そして実際、C#コンパイラはこれを利用しています!ユーザーコードから直接呼び出すことはできませんが、コンパイラーが生成したメソッドの「読みにくい名前」を生成します。

これがC#ではなくMSILに適しているのはなぜですか? MSILの使用例は完全に異なるため:

  • MSILは主要な開発言語として設計されていません。これは中間言語であるため、主な使用例は、コンパイラの出力を理解しようとするコンパイラ開発者向けです。
  • MSILはany以前のMicrosoft開発環境(.NET以前のVisual Basicやその他のOLE識別子にスペースを許可したオートメーションクライアントなど)と相互運用できるように設計されています。
  • 上で述べたように、関数の「言葉では言い表せない」名前を生成できることはバグではなく機能です。

識別子にスペースを含めることは良い考えでしょうか? 言語の使用例によって異なります。あなたがそれを許可するための確かなユースケースを持っているなら、必ずそれを許可してください。そうでない場合は、しないでください。

参考文献:複雑な識別子を上手に利用する魅力的な言語の例が必要な場合は、テキストベースのアドベンチャーゲーム用のDSLであるInform7を参照してください。

The Open Plain is a room. 
"A wide-open grassy expanse, from which you could really go any way at all."

これは、The Open Plainと呼ばれるroomタイプの新しいオブジェクトを宣言し、そのオブジェクトはプログラム全体でそのように参照できます。ご想像のとおり、Inform7には非常に豊富で複雑なパーサーがあります。

次に、より複雑な例を示します。

Before going a direction (called way) when a room (called next location) is not visited:
  let further place be the room the way from the location;
  if further place is a room, continue the action;
  change the way exit of the location to the next location;
  let reverse be the opposite of the way;
  change the reverse exit of the next location to the location.

waynext locationfurther placereverseはこの言語の識別子であることに注意してください。 next locationthe next locationがエイリアスされていることにも注意してください。 (エクササイズ:ゲーム内の部屋のマップを維持するデータ構造に対してこのコードは何をしているのですか?)

Inform7は、自然に見えるフルオンの英語をソースコードとして必要とする支持者を擁しています。このInform7を次のように書くのは奇妙に思えます

  change the way exit of the location to the_next_location;

そうすることは没入型破壊です。これをT. Sarの(優れた)回答と比較してください。これは対照的な点になります-LOB言語の開発者が識別子がどこにあるかを精神的に解析しようと試みることは没入型の破壊であるということです。繰り返しますが、それはコンテキストと目標に帰着します

59
Eric Lippert

比較的よく知られている は、単一のタイプミスがコードの意味を完全に変更した一部のFortranコードのものです。

コードのセクションを100回繰り返すことを意図していました(ループカウンターとしてIを使用)。

DO 10 I = 1,100

ただし、コンマはドットとして誤って入力されました。

DO 10 I = 1.100

Fortranでは識別子にスペースを使用できるため(宣言されていない場合は自動的に変数が作成されるため)、2行目は完全に有効です。暗黙的にDO10Iと呼ばれる疑似実変数を作成し、それに番号1.1を割り当てます。したがって、プログラムはエラーなしで問題なくコンパイルされました。ループの実行に失敗しただけです。

問題のコードはロケットを制御しました。ご想像のとおり、そのような間違いは壊滅的でした。幸いなことに、この場合、テストでエラーが検出され、宇宙船に害はありませんでした。

これは、識別子にスペースを許可する際の危険の1つをかなりよく示していると思います…

15
gidds

識別子にスペースを許可するのはプログラミング言語にとって悪い設計ですか?

重要な実装の詳細を忘れました:

ソースコード とは何ですか?

私は [〜#〜] fsf [〜#〜] 定義が好きです:開発者が作業するための好ましいフォームです。それは社会的な定義であり、技術的な定義ではありません。

一部の言語とその1980年代の実装(元の Smalltalk と1980 Smalltalkマシンを考えてみてください)では、ソースコードは文字のシーケンスではありませんでした。これは 抽象的な構文ツリー であり、ユーザーはマウスとキーボードを使用して、いくつかのGUIを使用して操作しました。

ある意味で、 Common LISP はその記号にスペースを受け入れます。

両方のプログラミング言語を共同設計することを決定できます(つまりlotの作業)(documented一部のレポートでは syntax と- semantics )、その実装(一部のソフトウェアとして)、およびそのエディタまたは [〜#〜] ide [〜#〜] (一部のソフトウェアとして)。

tunes.org に関する古い議論を読んでください。 INRIAの古い作品を読む

@TechReport{Jacobs:1992:Centaur,
 author =       {Jacobs, Ian and Rideau-Gallot, Laurence},
 title =        {a {\textsc{Centaur}} Tutorial},
 institution =  {\textsc{Inria} Sophia-Antipolis},
 year =         1992,
 number =       {RT-140},
 month =        {july},
 url =          {ftp://www.inria.fr/pub/rapports/RT-140.ps}
}

そして

@techreport{donzeaugouge:inria-mentor,
 TITLE =        {{Programming environments based on structured
                 editors : the \textsc{Mentor} experience}},
 AUTHOR =       {Donzeau-Gouge, Véronique and Huet, Gérard and Lang,
                 Bernard and Kahn, Gilles},
 URL =          {https://hal.inria.fr/inria-00076535},
 TYPE =         {Research Report},
 NUMBER =       {RR-0026},
 INSTITUTION =  {{INRIA}},
 YEAR =         1980,
 PDF =
              {https://hal.inria.fr/inria-00076535/file/RR-0026.pdf},
 HAL_ID =       {inria-00076535},
 HAL_VERSION =  {v1},
}

私の Bismonドラフトレポート および http://refpersys.org/ も参照してください

私のRefPerSysの夢は、そのような宣言型プログラミング言語をNice IDEで共同設計することです。10年かかる可能性があることはわかっています。ある意味で、私たちが狂っているとお気軽にどうぞ。私たちです!

使いやすさの観点から見ると、識別子のスペースよりも 構文の色分け および autocompletion の方が重要です(- GtkSourceViewCodeMirrorの両方を調べてください) インスピレーション)。視覚的にアンダースコア_はスペース文字に近く見えます。独自のIDEをコーディングすると、 ctrlspace 「名前内のスペース」の入力として。私の意見では、ℕと∀は「キーワード」である必要があります。問題は、どのように入力するかです。タイピングを夢見ています(LaTeXに触発されました) \forallESC ∀を取得するには(そして、そのための emacs サブモードについて聞いたことがあります)。

注意:私はPython(and Makefile -s))が嫌いです。空白(またはタブ)がそこにあるからです。

シンボル名にスペースを許可することは、本質的に悪い設計ではありません。これは単純な反例で示すことができます。

Kotlinでは、名前にスペースを使用できます。 この機能を使用しても問題ない場合

テストメソッドの名前

テスト(およびテストのみ)では、バッククォートでスペースを囲んだメソッド名を使用できます。

例:

class MyTestCase {
     @Test fun `ensure everything works`() { /*...*/ }

「良い」と「悪い」はもちろん主観的ですが、テストメソッド名にスペースを使用すると、テストコードが読みやすくなり、テスト結果も読みやすくなります。テストコーダーは、醜いメソッド名と人間が読める形式のテストの説明。

ここで重要な点は、これらのメソッドは通常、人間によって書かれたコードから明示的に呼び出されないため、名前が表示される場所はメソッド定義にあることだけです。これは、シンボル名でスペースが適切な場合があることを考慮するための重要な違いだと思います。つまり、プログラマーがシンボルを1度だけ書いた場合のみです。

6
hyde

経験則:

エラーは、コードを読み上げるのにかかる時間に比例します。

左角括弧、右角括弧、左中括弧、右中括弧、左括弧、右括弧の数を増やすと、コード内のエラーの数が増えます。

これが*が星またはスプラットであり、アスタリスクではない理由の1つです。 #はshhhです!強打です。私の疑いのある数学者も、彼らのシンボルについて短い言葉の表現を持っていると私は確信している。

それが技術分野が頭字語と略語で満たされる理由です:私たちは言葉で考えます。私たちは有限の注意スパンを持ち、頭の中に非常に多くのシンボルしか保持できません。だから私たちはグループ化し、物事をまとめます。

ReallyReallyLongIdentifierでも同じことができます。そこでは、それが何のためにあるのかを覚えることと、私たちの思考プロセスに巻き込まれることの間のトレードオフがあります。しかしReallyReallyLongIndentiferはQzslkjfZslk19よりも優れています

それが作成されたものから遠ざかるほど、記憶に残る必要があります。したがって、ループ構造に使用されるi、j、k-ループの存続期間にわたって生存するカゲロウのように、そのループは同じ画面で開始および終了します。

これはコーディングにも拡張されます。

A = FunctionAlpha(21、$ C、$ Q)

B = FunctionBeta($ A、$ D、$ R)

よりきれいです

B = FunctionBeta(FunctionAlpha(21、$ C、$ Q)、$ D、$ R)

これが、スプレッドシートにこのようなひどいエラー率の悪いコーディングがある理由の1つだと思います。一時的なセル/行/列を追加しない限り、乱雑なネストされたステートメントを回避する方法はありません。

3

本当に最高の言語が存在することは決してないということを本当に理解するのに長い時間がかかりました。プログラミングチームにとって最も重要な側面は、言語がよく知られており、多くのツールでサポートされていること、最小限の言語構文を備えていること、そしてできるだけまれにあなたを驚かせないことです。

単一のコーダーにとって、迅速なテスト/実行サイクルを可能にする強力な言語は素晴らしいです。

管理者にとって、オペレーティングシステムのシェル言語に合わせた言語は重要です。

分野間で共有されている一部の実用的な言語では、DSLが適切な場合があります。

スペースがある言語の場所はありますか?これは当然のルールに違反しますが、DSLの目標に非常によく適合します。

しかし、カスタムIDEを使用すると、実際にはハードスペースとソフトスペースが存在する可能性があります。それらは似ているように見えます(IDEで異なる色合いを持つ可能性があります)。 。

さらに言えば、今すぐ任意の言語でそれを行うことができます。アンダースコアをスペースとして表示するには、IDEのトグルをオンにします。Eclipseプラグインを作成する人なら誰でも、おそらく1時間でこれを実行できます。

キャメルケースを「スペースのある単語」に実用的に変換することもできます。IDEはそれを実行できますが、少し奇妙です。

0
Bill K