web-dev-qa-db-ja.com

頻繁に使用するプログラミング言語で最も嫌う構文要素は何ですか?

プログラミング言語がどれほど好きでも、常にいくつかの詳細があり、それが可能な限り素晴らしいとは言えません。

この質問では、構文要素に特に焦点を当てたいと思います。頻繁に使用するプログラミング言語(おそらくお気に入りのプログラミング言語、またはおそらくあなたが仕事で使用することを余儀なくされているもの)、どの構文要素が最も読みにくい、不明確、不便または不愉快だと思いますか?

26
Timwi

JavaScriptでのセミコロン挿入。

よく噛まれたことはあまりありませんが、頭が回転してしまうほどの驚異的な考えです。


ここにルールがあります(ECMA-262セクション7.9から)

  1. プログラムに正式な文法で許可されていないトークンが含まれている場合、(a)その時点で改行があるか、(b)予期しないトークンが右中括弧だった場合、セミコロンが挿入されます。
  2. ファイルの終わりに達したときに、プログラムを他の方法で解析できない場合は、セミコロンが挿入されます。
  3. 「制限された生成」が検出され、文法に「[LineTerminatorはここにありません]」という注釈が含まれている場所に行終端文字が含まれている場合、セミコロンが挿入されます。

例:

return 1; // returns 1

return
1; // returns undefined
39
Tim Goodman

C#プロパティの不足によるJava-bean構文

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}

GAH !!!

これで私が抱えている問題

  • コードが多すぎる-文書化されたフィールド、文書化されたゲッターメソッド、および文書化されたセッターメソッドがあります。この非常に基本的な例には、singleプロパティの20行のコードがあります
  • メソッドリストを整理する-「そのメソッドを見つけて、手渡し:getXgetYgetZgetAnotherAnnoyingFieldgetWhyIHateJavaBeansgetThisIsVerbosegetGAH...ああ、それはhashCodeです。
  • ドキュメントの複数の領域により、ドキュメントの品質が低下したり、古くなったり、欠落したりします-コードの機能を理解しようとすると煩わしい
  • そのため、サードパーティが煩わしいのは、これを簡単に行うためのプラグインを考え出す必要があったことです- スプーンサメ とりわけ。
39
TheLQ

空白の感度。

Pythonはこの点で私を困らせます。とにかく、私はとにかく適切にインデントしますが、haveを実行する必要があるというバグがあります。構文をプレゼンテーションの一部にすることは私に不快です。

32
Fishtoaster

switchステートメント(C、C++、C#、Javaなど)

これが私が非常に不便だと思う理由の例です:

switch (someVariable)
{
    case 1:
        int i = something();
        doSomething(i);
        break;

    case 2:
        int i = somethingElse();
        doSomethingElse(i);
        break;
}

変数iが同じスコープで再宣言されているため、これはコンパイルされません。これは些細なことのように思えますが、私は本当によく噛みます。中括弧を追加して緩和することもできますが、中括弧が構文の必須部分であり、余分なレベルのインデントがなければ、それはいいことです。また、余分なbreakを記述する必要もありません。これはずっといいでしょう:

switch (someVariable)
case 1
{
    int i = something();
    doSomething(i);
}
case 2
{
    int i = somethingElse();
    doSomethingElse(i);
}
default
{
    ...
}

これにより、if/elseチェーンのように見えます。これは、意味的にも類似しているため、良いことです。ただし、少なくともC#では同じではありませんが、switchステートメントではケースラベルの順序は重要ではありませんが、if/elseでは重要です。

32
Timwi

VB.NETの配列宣言

VB.NETで固定配列を初期化するときは、配列の上限とnot C/C++、PHP、またはJavaのような要素の数を指定していることを忘れてしまいます。 VB6(私たちはそこには行きません...)の他に、私はこのようにそれを行う別の言語を考えることができません:

Dim myArray(20) as Integer  '# Creates an array with 21 elements,
                            '# indexed from 0 to 20
27
user95

VB6-個別の変数宣言と割り当て

ほとんどの言語では、変数を宣言して1行のコードで割り当てることができます。一方、VB6では2つ使用する必要があります。

Dim i as Integer
i = 0

Dim derpderp as Collection
Set derpderp = new Collection

コロンを使用して1つの行に2つのコマンドを配置できますが、実際のコードではすぐに乱雑になります。

Dim i as Integer: i = 0
Dim derpderp as Collection: Set derpderp = new Collection
24
derekerdmann

CSSでのコメント

//は、PHPおよびJavaScriptのような他の多くの言語でそうであるように、コード行をコメント化しません。ただし、/* this is commented out */機能します。私は//

CSSを編集していることを忘れてから、戻ってエラーを修正する必要があるので、これは厄介です。

24
Talvi Watia

PHP-引数の一貫した順序

PHPには、配列または文字列に対して考えられるほとんどすべての操作を実行するための便利な関数がいくつかあります。これらの操作の多くは、$needle$haystack、しかし、異なる関数はそれらを異なる順序で受け取ります。どの関数がどの引数を必要とするかは、どれほど頻繁にそれらに遭遇しても、私の脳が吸収することを拒否する事実の1つです!

関数 in_array および strstr を使用します。

// Check whether $needle occurs in array $haystack
bool in_array (mixed $needle, array $haystack [, bool $strict])

// Check whether $needle is a substring of $haystack
string strstr (string $haystack, mixed $needle [, bool $before_needle=false])

おかしなことに、PHPはすべての文字列関数が$haystack, $needle一方、配列関数はその逆ですが、これはPHPを初めて使う人に慣れるのに少し時間がかかる場合があります。 ExpressionEngineへの投稿 この特定の癖について詳しく説明しているほか、 PHPバグリスト に関するディスカッション)があります。 PHPチームからの非常に短い応答が特徴です!

[email protected]
適切なIDE thenを使用します。
20
ConroyP

Python

インスタンスメソッド定義のselfパラメータ

19
Goran Peroš

Java

限目。フルストップ。物語の終わり。

どこから始めれば?ああ、どこから始めればいいのかわかります。Javaはめちゃくちゃ複雑で醜く、愚かで、本質的に壊れているジェネリックです。もっと言う必要がありますか? :( Ok fine、then: type erasure

次に、非決定論的なリソース管理があります。 Kewl Footcher!

次は何ですか?そうそう: Javaの愚かな正規表現 は、私にとって最も苛立たしい熱狂的な牛肉です。十分なバックスラッシュがないために何回ホーズされたかは数えられません。これは、完全に強大であるこの千年紀のUnicodeプロパティにアクセスできないよりもさらに悪いことです。 10年の古い年月が経ちました!!! 完全に役に立たない。ゴミ箱。

次に、文字クラスのショートカットが非ASCIIで機能しないというバグがあります。なんて王室の痛みだ!また、_\p{javaWhiteSpace}_の使用も考慮しないでください。いくつかの非常に一般的なUnicode空白コードポイントでは正しく動作しません。

_\p{javaJavaIdentifierStart}_プロパティがあることをご存知ですか?彼らが考えているのは何ですか?彼らがそんなに賢いのぞき見者を手に負えなくてうれしい。

Canon_EQフラグを使用しようとしたことがありますか? 本当にが行うことと、それがしない/をしていないことを知っていますか?いわゆる「Unicodeケース」はどうですか?通常のケーシングの多くはまったく機能しません。

次に、保守可能な正規表現を書くのを難しくします。 Javaはまだ複数行の文字列の書き方を理解していないため、次のような狂ったものを書くことになります:

_    "(?= ^ [A-Z] [A-Za-z0-9\\-] + $)      \n"
  + "(?! ^ .*                             \n"
  + "    (?: ^     \\d+      $            \n"
  + "      | ^ [A-Z] - [A-Z] $            \n"
  + "      | Invitrogen                   \n"
  + "      | Clontech                     \n"
  + "      | L-L-X-X                      \n"
  + "      | Sarstedt                     \n"
  + "      | Roche                        \n"
  + "      | Beckman                      \n"
  + "      | Bayer                        \n"
  + "    )      # end alternatives        \n"
  + ")          # end negated lookahead   \n" 
_

これらの改行は何ですか?ああ、Java愚かさ。彼らは、Javaコメント( idiots!)ではなく、Perlコメントを使用したつまり、これらの_\n_をそこに配置しない場合、パターンの残りの部分を切り捨てます。

Javaで正規表現を使用しないでください。結局のところ、物事を粉砕したいと思うだけで、それは非常に苦痛で壊れています。私はこれを我慢するなんて信じられない。 一部ではありません

次に、Javaのばかばかしい意味のないエンコーディングについて話し始めます。まず、JavaのcharcharがUnicodeであっても、デフォルトのプラットフォームエンコーディングは常に一部の不完全な8ビットエンコーディングであるという事実があります。次に、エンコーディングエラーで例外を発生させない方法があります。あなたはがらくたになることが保証されています。またはこれはどうですか:

_OutputStreamWriter(OutputStream out) 
          Creates an OutputStreamWriter that uses the default character encoding.
OutputStreamWriter(OutputStream out, Charset cs) 
          Creates an OutputStreamWriter that uses the given charset.
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 
          Creates an OutputStreamWriter that uses the given charset encoder.
OutputStreamWriter(OutputStream out, String charsetName) 
          Creates an OutputStreamWriter that uses the named charset.
_

違いは何ですか? エンコーディングエラーがある場合、そのうちの1つだけが例外を発生させることをご存知ですか?残りはそれらを口輪にします。

次に、ばかげたJava charsは文字を保持するのに十分ではありません!彼らは何を考えているのですか?それが私がcharcharsと呼んでいる理由です。それが機能することを期待するなら、このようなコードを書かなければなりません。正しい:

_private static void say_physical(String s) { 
    System.out.print("U+");
    for (int i = 0; i < s.length(); i++) {
        System.out.printf("%X", s.codePointAt(i));
        if (s.codePointAt(i) > Character.MAX_VALUE) { i++; }  // UG!
        if (i+1 < s.length()) { System.out.printf("."); }
    }
}
_

そして、whoがこれをやろうと思ったことはありますか?誰の隣にも。

_"\uD83D\uDCA9"_には何文字ありますか?一つか二つ?あなたがそれらを数える方法に依存します。もちろん正規表現エンジンは論理文字を扱うため、パターン_^.$_は成功し、パターン_^..$_は失敗します。この狂気はここに示されています:

_String { U+61, "\u0061", "a" }  =~ /^.$/ => matched.
String { U+61, "\u0061", "a" }  =~ /^..$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^.$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^..$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^.$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^..$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^.$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^..$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^.$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^..$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^.$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^..$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "????" }  =~ /^.$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "????" }  =~ /^..$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "????????" }  =~ /^.$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "????????" }  =~ /^..$/ => matched.
_

ばかばかしいのは、完全に合理的な_\u1F4A9_を記述できないことです。もちろん、それができないという警告も表示されません。それはただ間違ったことをします。

Stoooopid。

その間、_\uXXXX_表記全体が先天的に脳死しています。 Javaプリプロセッサ(はい、聞いたことがある)はJavaが実行する前に取得するため、禁止されています_"\u0022"_のような完全に合理的なものを書くことから、その時までにJavaがそれを見ると、そのプリプロセッサがそれを_"""_に変えたので、あなたは負けます。まあ、 not 正規表現の場合!_"\\u0022"_を使用できます。

いいね!

Javaを呼び出してisatty(0)を呼び出す方法がないことを知っていますか?あなたはそのような考えを考えることさえ許されていません。それはあなたにとって良くないでしょう。

そして、クラスパス全体の嫌悪感があります。

または、あなたのJavaソースファイルその同じソースファイル)のエンコーディングを指定する方法がないので、それを失うことはありませんか?もう一度私は知ることを要求します:彼らは何を考えていたのか‽‽‽

狂気を止めろ!私はこのゴミに我慢するなんて信じられない。それは完全な冗談です。私はとんでもないJava狂気のスリングと矢に苦しむよりもウォルマートの挨拶になりたいです。それはすべて壊れており、彼らはそれを修正できないだけでなく、勝ちました't 修正してください。

これは、printf()関数を持つことを違法にした言語を誇りに思っている、同じ悪意のあるブドウの人々によるものです。ええ、あれ確かにうまくいきましたよね!?

薄手のしびれ。ビッチの平手打ちは彼らにとってあまりにも親切です。アセンブラでプログラミングしたい場合は、そうします。これは救済可能な言語ではありません。皇帝は服を着ていません。

嫌いです。私たちはそれを嫌います forever die

18
tchrist

CおよびC++での関数ポインター宣言の構文:

(int)(*f)(int, int);

これはfという名前の関数ポインタを宣言しています。そのポインタは2つのintsを取り、intを返すことができます。

私はこのような構文をはるかに好みます:

f: (int, int) => int

関数ポインタgを宣言したいとします。そのポインタは、2つのintsと、intおよびintからintまでの関数を取ることができます。 intを返します。

CまたはC++表記では、次のように宣言します。

(int)(*g)(int, int, int(int, int));

上記の表記法を使用して、同じことを次のように宣言できます。

g: (int, int, (int, int) => int) => int

後者ははるかに直感的なIMOです。


余談:OOCと呼ばれるプログラミング言語は、この構文(およびCおよびC++におけるその他のさまざまな構文上の問題)を修正します。そのホームページをチェックしてください here

16
missingfaktor

Javaの冗長性。

つまり:

public static final int 
14
OscarRyz

PHPの\ we\wouldnt\fix\our\parser名前空間構文

構文は見苦しいだけでなく、新しい開発者が文字列の名前空間について考える必要がある場合に混乱を招きます。 (PHPは二重引用符で囲まれた文字列のバックスラッシュをエスケープシーケンスとして補間します。\you\should\never\do\thatのような名前空間を単一引用符で囲まれた文字列ではなく二重引用符で囲まれた文字列で表現しようとすると、改行、タブ、および障害が発生します。)

12
mario

VBScriptには論理演算子がありません

ほとんどすべての実用的な言語とは異なり、VBScriptは論理演算子の代わりにビット演算子を使用します。これは実際にはどういう意味ですか? Eric Lippertが指摘しているように

If Blah = True Then Print "True!" Else Print "False!"

そして

If Blah Then Print "True!" Else Print "False!"

vBScriptでは同じではありません!

さらに悪いことに、これはVBScriptに短絡評価がないことを意味するため、BlahNothingの場合、次のステートメントはプログラムをcrashします。

If (Not Blah Is Nothing) And (Blah.Frob = 123) Then
...

そうです、VBScriptは、最初の比較が偽の場合でも、AND比較のboth部分を評価します!ただ沈ませるだけ...

9
Dan Diplo

中括弧は、if/while/forステートメントの後にオプションにすることができるという事実を軽視します。

特に私が次のようなコードを見るとき、

if (...)
    for(...)
        ... One line of stuff ...

中かっこを入れて完了です。

9
Jim A

編集:コメントでの議論に続いて、私は自分自身をよりよく説明するためにこの回答を更新することにしました。

Cでの関数ポインターの見え方が本当に嫌いです。通常、変数宣言は次のタプルのように見えます:type varname;一方、関数ポインタ宣言は、関数名の前に*がある関数の宣言のように見えます。これをポインタ型の説明として受け入れることはできますが、Cでは、型とその型の変数の名前の両方を宣言しています。タイプ宣言は変数宣言とは別の方法であるため、これは私には矛盾しているように見えます。 struct myStruct{int X; int Y;}はタイプを定義するだけで、myStructという名前の変数は定義しません。同様に、関数宣言で型宣言と変数宣言を1つのatomicステートメントにグループ化する理由もわかりません。また、type varname;構造。

スパイラルルールと一致していると誰かが指摘しましたが、そうかもしれませんが、優れた構文の特徴は、それが自明であり、その内部ロジックが明白であることです。螺旋状の法則は決して明白ではありません。

7
EpsilonVector

入出力引数。私はすべてinの議論に賛成です(いいことですが)outの議論も問題ありませんが、これら2つの状態を伝える必要のある議論は私を怒らせます。

ここで対象とするのは、パラメーターから入力を受け取り、その入力をいくつかの出力で上書きする関数です。参照によってオブジェクトを渡して更新することは問題ありません。しかし、ほとんどのプリミティブ型では、オブジェクトを取得し、それを使用してから、完全に変更することは私には適切ではありません。入力を通じて、引数の意味を変更しないでください。

6
zneak

VBScriptのセミコロン-またはその欠如

私は、各行の終わりにセミコロンが必要な言語で一日中働いています。 VBScriptの行の最後に1つ追加すると、コードは実行されなくなります。

6
Nathan Taylor

CおよびC++での配列宣言。

通常、変数宣言の形式はtype variable_nameです。これらの宣言は、左から右に簡単に読むことができます。ただし、int foo[size]は、最初にfooをintとして宣言しているように見えます。次に、さらに読むと、fooの型が「整数の配列」であることがわかります。 int[size] fooははるかに読みやすくなります。

また、プログラマが同様の理由でこのようなポインタを宣言する場合も、私はそれを嫌います:int *foo。何らかの理由で、私は理解していませんが、それはtypicalの記述方法です。

6
Jacob

Javaでの冗長パラメーター化:

HashMap<String,HashMap<String,String>> foo = new HashMap<String, HashMap<String, String>>();

コンパイラーは他にどのような型のパラメーター化thinkfooを使用できますか?

5
Hoa Long Tam

人々はすでに===について不平を言っているので、もっと悪い代替案を指摘させてください。 PL/Iには:==の両方がありましたbut何かが「明らかに」割り当てだった場合、=を使用してそれを回避できます。 :=を使用すると、コンパイラーが比較として解釈する状況で、何かを強制的に割り当てにすることができます。

残念ながら、コンパイラーは常にあなたが期待する方法で物事を決定するとは限りませんでした。明白な例を1つだけ考えてみましょう。

A = B = 0;

さて、ほとんどの「通常の」言語に精通しているほとんどの人にとって、これの意味はかなり明白です。AとBの両方に0を割り当てます。PL/ Iは少しだけ...でも違います。言語の(非常識な)設計者のみが知っている理由により、最初の=は代入として解釈されますが、2番目の=は比較として解釈されます。したがって、これはBを0と比較し、その比較の結果をAに割り当てます(Cスタイルの規則に従って、 "false"は0、 "true"は1になります)。

したがって、Bが0の場合、Aは1になります。それ以外の場合、Aは0になります。つまり、AとBに同じ値を割り当てるのではなく、A cannotが確実に同じ値になるようにします。 Bとして.

結論:最初はC/C++/PHPスタイルseemsは苦痛のようですが、代替案ははるかに悪いです1

1技術的には、別の方法があります。Pascalスタイルです。ここで、=は常に比較を意味し、割り当てには常に:=が必要です。しばらくそれを使用した後、割り当ては比較よりも十分に一般的であることは(少なくとも私には)かなり明白です。2つを明確にするために追加の「もの」が必要になる場合は、割り当てを明確かつ単純に保ち、比較では追加の「グランジ」が必要で、その逆は必要ありません。

5
Jerry Coffin

JavaScriptの for ... in 構成体とPHPの foreach 構成体は、配列をループする場合。どちらも簡単に正しいコードよりもバグを書いてください。

3
Joeri Sebrechts

Perl

  1. Perlにif($x < 10) do_something();と書いてもらいたいのですが。現時点では、それをdo_something() if($x < 10);またはif($x < 10) { do_something(); }のいずれかとして記述する必要があります。
3
Gaurav

reinterpret_cast<unsigned long> c ++で。この操作は、外部APIを処理し、数値の精度を確保するのに役立ちます。なぜ、入力するのがそれほど面倒で、見にくいのでしょうか。

3
AShelly

配列のポインターまたはC/C++のポインターの配列。私はまだこれらについて混乱しています。

2
Casebash

Python=という事実は、テキストのフォーマットに依存しています。

2
Ashalynd

Java匿名クラスの冗長性。うまくいけばすぐに修正されるでしょう。

1
alex

structPointer->member C/C++では。他の人のコードを読むのには良いかもしれませんが、私はそれが好きではありません。 1つの文字ではなく2つの文字...スペースの無駄です。

これは古い質問であることは知っていますが、なぜ誰も言及していません。

コードナゲット

<% %> <-通常

<%= %> <-バッファロースタイル

<%:%> <-余分なサクサク

0
MVCylon

PHPのREGEX/preg_match()

最初に、PHPが使用するものとは完全に異なる構文です。preg_match()関数はregexを非常によくエミュレートしますが、それを使用するには、私の思考モードを完全に切り替える必要があります。

第二に、半分の時間でその単なる明白な覆い隠し。私は通常、文字通りスクラッチパッドを取り出して、WTFが半分の時間で実行されていることを理解する必要があります。

さらに、PerlではなくPHPでプログラミングします。 Perlが好きなら、Perlでプログラミングします。 (いいえ、私は好きではありません。)

さらに悪いことに、新しいPCRE区切り文字形式では、同じネストされた文字をエスケープし、パターンさらにを曖昧にする必要があるなど、実際に任意の文字を使用できます。

もちろん、暗号化したい場合や、効率を上げたい場合に最適です。

0
Talvi Watia

Scala複数行の括弧内コード

例えば:

class Foo(
         val bar: String,
         val baz: Int,
         val bing: String,
         val bong: Boolean
 ) extends Model {
   // body here
 }

あなたが実際にそれから得るものは素晴らしいです。コンストラクターとゲッターとセッターが生成されます。しかし、それは確かに醜く、コードをインデントする方法に関する私のすべてのメンタルモデルを壊し、基本的に、私は、Javaが片側にあり、LISPが反対側にあるような奇妙なサンドイッチにいるように感じます。(ああ、待ってください...それはむしろScalaのポイントです。)

0
Tom Morris