頻繁に使用するプログラミング言語で最も嫌いな構文要素は何ですか?[閉まっている]


27

プログラミング言語がどれほど愛されていても、その中にはあまり良いものではないいくつかの詳細が常にあります。

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


@Nathan Taylor、この質問ではなく、別の質問です。
finnw

この質問は修正されましたか?私が答えたとき、それは「構文要素」に焦点を合わせていなかったからです...私は今、私の答えを修正しなければなりません。
タルビワティア

@Talvi:いいえ、最初から構文についてでした。
ティムウィ

@Timwi変なのは、それが「違う質問だと思って質問に答える」場合だろう。
タルビワティア10

投票して、これが有用な質問であると思う場合、または以下に有用な回答がある場合は、投票してください。StackExchangeサイトは、優れたコミュニティを構築するために投票が必要です。1日に30票を投じることができます。無駄にしないでください。:特別高い評価と低カウントを持つユーザーが指定した投票このお読みくださいmeta.programmers.stackexchange.com/questions/393/...
Manieroの

回答:


39

JavaScriptでのセミコロン挿入。

あまり噛まれたことはありませんが、頭が回るほど驚くほど悪い考えです。


ルールは次のとおりです(ECMA-262セクション7.9から)

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

例:

return 1; // returns 1

return
1; // returns undefined

2
JavaScript:世界で最も誤解されているプログラミング言語
〜Douglas

はい、多くの人はJavaScriptが「自由形式の言語」であることを期待していますが、そうではありません。
アンドレアスレイブランド

13
JavaScriptがHTMLを作成するために設計されていることを理解すると、それは意味があります。(ロバストネス原則をいつか調べてください。これはコンピューティングの歴史上最大の災害です。)
Mason Wheeler

7
私にとってこれらのタイプのエラーは、プログラマがだらしなく、通常セミコロンを省くための構文エラーを引き起こすほとんどの正式な「厳格な」言語で動作したことのないコード臭です。
タルビワティア

7
Wohoo、最後に、Robustness PrincipleがHTMLをまったくの混乱に陥れた災害であると考える他の誰か。
ローマンスターコフ

39

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;
}

ああ!

私がこれに関して持っている問題

  • コードが多すぎる -文書化されたフィールド、文書化されたゲッターメソッド、文書化されたセッターメソッドがあります。この非常に基本的な例には、1つのプロパティに対して20行のコードがあります
  • クラッタ方式リスト - 「私はその方法、手持ちのを見つけてみましょう:getXgetYgetZgetAnotherAnnoyingFieldgetWhyIHateJavaBeansgetThisIsVerbosegetGAH...ああ、それは、そこにありますhashCode
  • ドキュメントの複数の領域は、ドキュメントの質が低い、古くなっている、または欠落している -コードが何をするのか理解しようとすると面倒
  • サードパーティは、簡単にこれを行うには、プラグインを思い付くためにとても迷惑だった - スプーンシャーク中でもを、。

9
繰り返しますが、コードが非常に冗長であるため、自動生成ツールが必要な場合、何か問題があります。私はNetBeansの男ですが、ゲッターとセッターを自動生成する機能も備えています。しかし、Javadocはsynから外れ、まだ冗長であり、javadocを
乱雑にします-TheLQ

11
すべてにゲッターが必要な場合は、クライアントコードに何か問題があります
finnw

7
ゲッターとセッターがあるとカプセル化が壊れます。フィールドも同様ですpublic。メンバーはプライベートである必要があり、クライアントコードからのゲッターとセッターではなく、より高いレベルのロジックを持つクラスによって賢明に操作される必要があります。
greyfade

6
@greyfade:パブリックの場合、設定コードの動作を簡単に変更することはできません(外部からフィールドを設定するすべてのコードを変更する必要があります)。
バートヴァンヒューケロム

3
@SHiNKiROU:Javaはきれいに見えますか?私はそれを聞いたことがありません!私のJavaの主な不満は、一見シンプルに思えるのに、精神的に無視する必要のある数十行のコードが必要になるという事実です。
コンフィギュレー

33

空白の感度。

Pythonはこの点で私を困らせます。とにかく適切にインデントしますが、それは私がしなければならないバグです。プレゼンテーションの一部を構文の一部にすると、私はいらいらします。


8
あなたはそれを愛することを学ぶでしょう
-user10008

2
構文プレゼンテーション
ウィンストンユーバート

32

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ません。ステートメントではcaseラベルの順序は重要ではありませんが、if/ elseでは重要だからです。


1
残念ながら、改善された構文は、これらの言語のほとんどで間違いなくスイッチの最大の機能であるフォールスルーを排除します。Cの「Duff's Device」は、この特定の「誤機能」の価値の完璧な例です。Cライクな言語では、通訳や同様のプログラムでフォールスルーを使用することも一般的です。
greyfade

7
いいえ、それは廃止しません。gotoC#で既に行われているように、より明示的に(または同様のものを使用して)作成するだけです。
ティムウィ

8
@greyfade:Cでduffのデバイスを使用するコードは、恐ろしい死を遂げる必要があります。コンパイラは、これらの種類のことについて、あなたよりも良い決定を下します。
ビリーONeal

4
@greyfade:Delphiは、次の場合に複数のインデックスを許可するだけで、複数の値の問題を回避しますcase Foo of 1,3: Result := 'odd'; 2,4: Result := 'even' end;
フランクシェラー

3
@jkerian:ここbreakで、デフォルトがデフォルトであり、指定する必要があるのはフォールスルーだけだと想像してください。コメントする必要はもうありません!:)
ティムウィ

27

VB.NETでの配列宣言

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

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

私はすべてのBASIC言語がこれを行うと思います...私はオリジナルのBASICとQBasicがすることを知っています。
マイケルK

本当に恐ろしいOMG .... +1
mikera

25

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

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

Dim i as Integer
i = 0

Dim derpderp as Collection
Set derpderp = new Collection

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

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

7
最も頻繁に使用する言語としてVB6を使用する必要があるため、+ 1。
ウォルター

9
毎日使います。
systempuntoout

Pascalにも同様の構文はありませんか?私はいつもそれが嫌だと思っていました。
greyfade

1
特別な場合があります:を参照するときにDim Hurp As New CollectionアクセスHurpするとNothing、アクセスする前に魔法のように初期化されます。明示的に設定しNothingて再度タッチすると、復活します...あえぎます!
ジェフリーハンティン

1
Derpに対して+1ミリオン。Derp de derp de tiddly tum de derp。
MVCylon

24

CSSでのコメント

//PHPやJavascriptなどの他の多くの言語でのように、コード行をコメントアウトしません。けれども/* this is commented out */作品、私が使用することを好みます//

迷惑なのは、CSSを編集しているときに忘れて半分の時間を過ごした後、戻ってエラーを修正する必要があるためです。


あなたはこの日と時代において、生のCSSはオブジェクトコードと見なされると考えていたでしょう。
トムホーティン-タックライン

// CSSをコメントアウトするのにうまく機能します。私はいつもそれをします。私が本当にしていることは、ゴミを入力することだけです。しかし、解析不能な行をスキップすることで動作するようです。
MVCylon

1
@MVCylon //を使用して行をコメントアウトすると、その次の行以降もスキップされます。{その特定のスタイル内}つまり、これらの行をスキップしてはならないため、失敗します。
タルビワティア12年

20

PHP-引数の一貫した順序

PHPには、配列または文字列で考えられるほぼすべての操作を実行するための便利な関数が多数あります。これらの操作の多くはa $needleとaの両方を使用する必要があります$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バグリストに関する議論もあります。

helly@php.net
その後、適切なIDEを使用します。

2
これは、順番を覚えておく方が簡単です$needle$haystackそれは言うの道連想させるとして、干し草の山で針を見つけることを
キアムルノ

3
ヒント:配列関数では、針が最初に来ます。文字列関数では、haystackが最初に来ます。
GSto

17
名前が大好きstrstrです。とても美しく無意味。
コンフィギュレー

5
PHPのバグトラッカーでリンクされたエントリを読むだけです。真剣に、WTF?oO Imhoの一貫性はどのAPIにとっても有効な問題であり、「適切なIDEを使用する」という応答は有効な返信ではありません。少なくとも、開発者たちはあまり炎症性がないと言われたかもしれません。
バエルノーン

2
正直なところ、私がこれに夢中になっているのは、それが機能であってはならないということです!メソッドである必要があります:$ haystack-> find($ needle)。完了しました。
リウォーク

19

Python

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


クラスメソッドでは、通常clsという名前が付けられ、selfの使用は慣例に反します。

あなたがそれについて考えるならば、それは実際に理にかなっています。これは、他の言語でプライベートメソッドを宣言するのと同じです。selfパラメータは、他の言語で暗黙的であるpythonで明示的です。暗黙的にする場合は、メソッド宣言の前に@classmethodデコレーターを追加します。docs.python.org/library/functions.html#classmethodを参照してください。これがどのように機能するかの詳細を学ぶことは、暗黙的に他の言語でどのように行われるかについての洞察を与えます。
エヴァンプライス

4
私はその理由を理解し、なぜそれがそこに残っているneopythonic.blogspot.com/2008/10/...が、私はまだそれ好きではない
ゴラン・ペロス

@Evan Plaice:「selfパラメータは、他の言語では暗黙的であるpythonでは明示的です」それは物語の一部にすぎません。他の部分は、毎週入力されるpythonです。一緒にそれはひどいです、忘れるselfことは簡単に起こり、時間を要します。
maaartinus

@maaartinus次に、インスタンスメソッドにclassmethodデコレータを追加します。「弱い入力」とは何の関係もありません。静的メソッド/関数( 'self'パラメーターなし)とインスタンスメソッド( 'self'を含む)の関係が明確になるだけです。インスタンスメソッドは、そうするための参照を与えない限り、その親クラスを認識しません。他の言語では、私が概説した際立った特徴は、構文糖の後ろに隠れています。私がそれをすべてする選択があったなら、私は最初にPythonでOOPを学び始めたでしょう。
エヴァンプライス

18

Java

期間。完全停止。話の終わり。

どこから始めれば?ああ、私はどこから始めるべきかを知っています:Javaのめちゃくちゃ複雑でく、愚かで本質的に壊れたジェネリック。もっと言う必要がありますか?:(大丈夫、その後:erasureと入力します。

次に、非決定的なリソース管理があります。ケウル・フッチャー!

次は何?そうそう: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コメント(ばか!)ではなく、Perlコメントを使用しました。そのため、それら\nのをそこに配置しない場合、パターンの残りの部分を切り落とします。当たり前とダブル当たり!

Javaで正規表現を使用しないでください:物事を壊したいだけになります、それはすべてとても痛くて壊れています。私は人々がこれに耐えることを信じることができません。 しない人もいます。

次に、エンコーディングのJavaのばかげたナンセンスについて話し始めることができます。まず、Javaの文字が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のcharの白痴があります!彼らは一体何を考えているのでしょうか?それが私がそれらを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("."); }
    }
}

そして、誰がそれをすることを考えていますか?誰の隣にも。

キャラクターは何人い"\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もちろん、あなたはそれができないという警告を受け取りません。間違ったことをするだけです。

愚かな。

私たちがそれに取り組んでいる間、\uXXXX記法全体は先天的に脳死です。Javaのプリプロセッサは(はい、あなたは私を聞いた Javaはありません前にはのような完全に合理的なものを書くことから禁止されているので)、それを取得"\u0022"するJavaはそれを見ている時間によって、そのプリプロセッサはにそれを回したので、"""あなたが失うので、。ああ、待って、それが正規表現である場合ではありません!だからあなたは"\\u0022"うまく使うことができます。

いいね!

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

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

または、同じソースファイルに Javaソースファイルのエンコーディングを指定する方法がないため、失わないようにしますか?もう一度私は知っておく必要があります:地獄はでしたか?

狂気を止めろ!私は人々がこのゴミに耐えるなんて信じられない。それは完全な冗談です。私は、とんでもないジャワの狂気のスリングや矢に苦しむよりも、むしろウォルマートのグリーターになりたいです。それはすべて壊れており、彼らそれを修正できないだけでなく、修正もしません。

これは、printf()機能を持つことを違法にした言語を自慢した同じ愚かな人によるものです。ジー、それは確かに本当にうまくいきましたが、そうではありませんでした!?

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

嫌いです。私たちはそれを永遠に嫌います。ダイダイダイダイ


ハハ、良いもの、私はあなたが説明するようにあまりにも洗練されていないので、Javaに触れません。\ uD83Dについては...まあ、これを言うより良い方法は、文字列がUTF-16ではなくUTF-32であった方が良いと思います。UTF-16-nessを受け入れる場合、正規表現は正しいことを行います。失敗するのは.length呼び出しです。
ローマンスターコフ

4
-1。正規表現のコメントとUnicodeエスケープを除き、あなたが言及したものの1つが構文要素ではありません。
ヨルグWミットタグ

3
@Jörg、構文が必要ですか?大丈夫:Javaでは、識別子にESCとNULを含む制御文字を入れることができます。WTHは彼らが考えていましたか???
tchrist

4
@tchrist:うわー!Javaプログラムを再度作成する場合、すべての変数にはさまざまな数のバックスペース文字(^H)で構成される名前が付きます:)
j_random_hacker

1
@tchrist、気分が良くなりましたか?

16

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

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

これは、ポイントf先が2を取りint、を返すことができるという名前の関数ポインタを宣言しますint

私はこのような構文をはるかに好むでしょう:

f: (int, int) => int

あなたが関数ポインタを宣言したいとしg、その指示先2取ることができますint秒からの機能intintint、およびリターンをint

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

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

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

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

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


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


同意して、一部の「プレーンC」/「C ++」は、それをサポートしていないか、異なる構文でサポートしています。特別な構文は、プログラミング言語機能がいつサポートされるかを示すのに役立ちます。それが、C#が「デリゲート」構文を追加した理由です。
-umlcat

参加者は、彼らはまた、(通常の関数ポインタよりもさらに悪い構文を持つC ++のメンバ関数ポインタに反して)オブジェクトが格納されるため、シンタックスシュガーであるだけでなく
タマシュSzelei

14

Javaの冗長性。

すなわち:

public static final int 

6
に比べ?(15文字)
TheLQ

7
と比較して:const int例えば。
OscarRyz

11
「public static final int x = 4;」Haskellの「x = 4」と比較してください。
Jaredアップダイク

24
それは冗長ではありません。Javaで記述a+(b*c)/d*e+f/g^20BigIntegerてみてください。なぜこの言語は演算子のオーバーロードを許可しないのですか?
MAK

4
@Michael:このコストで自分自身から保護する必要があるプログラマーは、まったくプログラミングしないことで、自分自身を最もよく保護できます(そして、他のすべての人の痛みを軽減できます)。
MAK

12

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

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


ええ、誰かがより良い::方法を考えましたが、PHPはすべての演算子が異なっていなければならないと主張しています。しかし、誤用の問題がここにあるかどうかに興味があります。
アラン・ピアース

同意する。PHPは名前空間を必要としますが、その構文はそれを
台無しに

9

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

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

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

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


6
うーん、これは依存します。条件をチェックし、エラーコードを返す(または例外をスローする)だけの「Ifを中止する」場合は、ブレースは表示しません。
ビリーONeal

4
あなたが極端なマルチレベルのケースに自分自身を制限した場合、私は同意するだろうが、あなたの声明はあまりにも包括的なです。単純な単一ステートメントのifおよびループの短い形式を使用できるという点で、非常に有用です。
ティムウィ

2
私の規則:ステートメントが複数のサブステートメントを必要とする場合、またはそのようなステートメント含まれる場合のみ、括弧で囲む必要があります。したがって、適切なインデントを使用して、もちろんにfor (...) while (...) if (...) { x(); y(); }書き直す方for (...) { while (...) { if (...) { x(); y(); } } }が適切です。
ジョンパーディ

6
私はむしろ反対です-彼らが完全に不要であるときにブレースを入れることを主張する人々を軽deします。プログラミングを学ぶだけです。
ジェリーコフィン

3
単一のifステートメントでも括弧が本当に好きです。これにより、プログラムの流れをよりよく追跡できます。
リカルドサントス

9

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

ほぼすべての実用的な言語とは異なり、VBScriptは論理演算子ではなくビット演算子を使用します。これは実際にはどういう意味ですか?まあ、ようエリックリペットは指摘します

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

そして

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

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

さらに悪いことに、しかし、次の文は、なるように、VBScriptのには短絡評価この手段がないことをクラッシュあなたのプログラムを場合Blah、ISは、Nothing

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

そうです、VBScriptは、最初の部分が偽であっても、AND比較の両方の部分を評価します!ただそれを...


3
内部でバグIf x Then ... If Not x Then ... End If ... End Ifを見つけてxが2であることが判明するまで、VB / VBScriptで実際にプログラミングしたことはありません。
コンフィギュレー

7

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

Cでの関数ポインターの見方は本当に嫌いです。通常、変数宣言は次のタプルのように見えます。type varname; 一方、関数ポインター宣言は、関数名の前に*が付いた関数の宣言のように見えます。私はこれをポインタ型の記述として受け入れることができますが、Cでは、その型の変数の型と名前の両方を宣言します。それ以外の場合、型宣言は変数宣言とは区別されるため、これは矛盾しているように見えます。struct myStruct{int X; int Y;}型のみを定義し、という名前の変数は定義しませんmyStruct。同様に、型の宣言と変数の宣言を関数ポインターで1つのアトミックステートメントにグループ化する理由も見当たりませんし、type varname;構造からの逸脱も認めません。

あるスパイラルルールと一致することを誰かが指摘しましたが、それは事実かもしれませんが、良い構文の特徴は、それが自明であり、その内部ロジックが明らかであることです。スパイラルルールは、決して明らかではありません。


1
それは他の言語と一貫しているので、あなたの不満は一般的にC宣言子の構文についてですか?Goで使用されている構文を好みますか?
finnw

どのように一貫していますか?通常は次のとおりです。varnameと入力します。そして、構造体のような新しい複合型を作成するとき、まずtypedefを含む宣言が最初に来てから、その型の変数を作成します。関数ポインターを宣言するとき、それはint(* foo)(int arg1、int arg2)であり、関数に渡される引数の型として使用されます:void newFoo(int(* foo)(int arg1、int art2 ))....そして変数として:foo = a_compatible_func; 次のように、最初に関数宣言、次にvar宣言の一貫性が高まると思います。typedef int(* foo)(int、int)MyFoo; MyFoo myfoo;
EpsilonVector

それがあなたが得typedefた理由です。
zneak

4
@EpsilonVector:関数ポインターの構文が厄介であることに同意する傾向がありますが、読みやすくするために従うべき単純なルールがあります。時計回りのスパイラルルール(おそらく見たことがあるでしょうか?):c-faq.com/decl/spiral.anderson.html
greyfade

1
EpsilonVector:ポインター変数宣言から変数名以外を宣言するために何を期待するのかわかりません。

6

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

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


4
これは、特にセミコロンが好きだからではなく、VBが改行を非常に不便にして本当に長い行を奨励する方法が嫌いだからです。
Shog9

6

入力/出力引数。私はすべての議論に賛成です(私は良いことです)、アウト引数も素晴らしいですが、これら2つの状態を伝えなければならない議論は私を怒らせます。

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


どの言語を考えていますか?C#の場合、(C ++とは異なり)常に明示的であるため、迷惑であることに同意しません。また、引数をin / outとして宣言することを余儀なくされる主流言語も知りません。
finnw

@finnwあなた議論のinためにあなた言う必要のある言語を見たことはありませんin、私はそれらについて話しているだけです。また、私の意見では、何も /アウト引数を言い訳することはできませんし、それらを明示的にすることは、痛みを緩和しません。ローカル変数を関数に役立つ値で初期化し、この同じ変数に関数がそこに置くことを決めたものを突然含める必要がある理由はないはずです。これら2つは区別する必要があります。常に。
zneak

申し訳ありませんが、私はあまり明確ではありませんでした。「すべての引数が暗黙的に+ outになっている言語は知らない」、つまりその機能の使用を強制されることはありませんが、正当な使用例があります(たとえばstruct、新しい値が値に依存する場所の更新同じ別のフィールドのstruct。)
finnw

@finnw class関数によって変更される参照によって渡されるオブジェクト(C#のオブジェクトのインスタンスなど)は、私にとっては問題ありません。定数でない構造体が嫌いなことはさておきstructrefキーワードでa を渡して更新することもできます。私が本当に嫌いなのは、入力が出力で上書きされるときです。私が考えることができる最良の例は、バークレーソケットのaccept関数です。socklen_t*入力には、struct sockaddr*渡したサイズを含める必要がある引数が必要です。出力には、書き込まれたバイト数が含まれます。これは犯罪的です。
zneak

私は同意します(IIRCの一部のWin32 I / O関数は同じことをします)が、それは機能の誤用です(関数呼び出しは値だけでなく、渡された変数の意味を変更します)、それは機能を意味するものではありませんそれ自体が悪いです。
finnw

6

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

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

また、プログラマーが同様の理由でこのようなポインターを宣言するときも嫌いですint *foo。どういうわけか私は理解していませんが、それはそれが書かれている典型的な方法です。


1
ポインター宣言について:「」は型ではなく変数名にバインドするint* a, b;ため、そのように書かれていますだから、*しない宣言abポインタとして。のみaです。したがって、次のように記述する方が適切ですint *a, b;(または、2つの宣言として記述する方が適切です)。
スティーブメルニコフ

いい視点ね。あまりにも悪い*ので、型にバインドしません。
ジェイコブ

2
そして、これは関数ポインターのことは言うまでもありません... void(int) *f;?いいえ:void (*f)(int);
自己への注意-

最新のC ++では、ポインターと配列はほとんど必要ありません。
fredoverflow

2
@Steve Melnikoff:この答えに+1を付けましたが、int* a, b;あなたが述べた問題はもっとひどいものだと思います。
j_random_hacker

5

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

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

コンパイラは、他にどのような型のパラメーター化を行うことができると考え fooていますか?


4
Javaの(制限された)型推論を知っていることを望みますか? HashMap<String,HashMap<String,String>> foo = Maps.newHashMap();
finnw

1
Java 7:HashMap<String,HashMap<String,String>> foo = new HashMap<>();
バートヴァンヒューケロム

5
まあ、それはそれが望む任意のタイプを持つことができ、タイプはとにかく消去されます
configurator

型推論の欠如、ということですか?
missingfaktor

What other type parameterization does the compiler think foo could have?-何らかの理由でそれは生のタイプです-誰かが正気で生のタイプとパラメータ化されたタイプを混在させるかのように。
-maaartinus

5

人々は既に=vs. について不満を述べているので==、もっと悪い代替案を指摘させてください。PL / Iは両方を持っていた:==しかし、何かが「明らかに」割り当てたとき、それはあなたが使用して逃げる聞かせ=それを行うこと。を使用:=すると、コンパイラがそれを比較として解釈するような状況で何かを強制的に割り当てることができます。

残念なことに、コンパイラは常に予想どおりに物事を決定するわけではありませんでした。明らかな例を1つだけ考えてみましょう。

A = B = 0;

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

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

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

1技術的には、別の代替=手段があり:=ます。パスカルスタイルでは、常に比較と割り当てが必要になります。しばらくそれを使用した後、割り当てが比較よりも十分に一般的であることはかなり明白です(少なくとも2つを明確にするために余分な「もの」が必要な場合は、間違いなく割り当てを清潔でシンプルにしてください)比較には余分な「グランジ」が必要であり、逆は必要ありません。


1
私は==平等と:=割り当てに使用することさえ提案します。このように入力する必要がありますが、孤独=を避けることはバグを避けるのに役立ちます。
-maaartinus

@maartinus:少なくとも私には、絶対的な最悪の可能性のような音が、そのようなものが人生であることを...
ジェリー棺

3

Perl

  1. Perlに書かせて欲しいif($x < 10) do_something();。現時点では、どちらかdo_something() if($x < 10);またはとして記述する必要がありますif($x < 10) { do_something(); }

9
do_something() if ($x < 10);悪くありません。
zneak

それはそうではなく、多くの場合if(..) ...、すべての式を右側に揃えることができるため、起動するよりもずっときれいです。しかし、私は本当に言いたいことがありますif($x < 10) do_something();、そして、Perlが私を許さないのは残念です。
ガウラブ

7
書いてif ($x<10) do_something(); and_call_me(); からなぜ電話をかけないのか不思議に思うまでは残念です。そのタイプのエラーを防ぐために、Cと家族が中括弧を必要とすることを望みます。
AShelly

2
@AShelly:または、実際に常に電話を受ける理由。
zneak

1
@zneakを除きelseます。(私はそれを持っていたいEXPR1 if COND else EXPR2Pythonが持っているように)
明唐

3

reinterpret_cast<unsigned long>C ++で。この操作は、外部のAPIを処理し、数値の精度を確保するのに役立ちます。なぜ入力するのがそんなに苦痛で、見るのがsoいのでしょうか?


17
それを必要としないコードを書くよう努力する必要があることを思い出させるのはいです。:)
greyfade

私にとっては、これは理論的なコンピュータサイエンスの一種の議論ですが、私の経験では、避けるのはあまりにも便利です(ただし、私の経験の多くは単純な古いCなので、おそらく偏見があります)。
AShelly

5
これは実際には理論上のCSの議論ではありませんreinterpret_cast。C++でa を使用することは非常に強力なコード臭です。99%の確率で、これを使用しようとするとき、チャンスがあります。必要はないはずです-おそらく何か間違ったことをしたでしょう。他の1%の時間、あなたはCとインターフェースをreinterpret_castとっています。そうしないと、型システムを壊して何かを機能させることができます。それは通常悪いことです。
-greyfade

3

JavaScript のfor ... inコンストラクト、および配列をループするときのPHP のforeachコンストラクト。どちらも正しいコードよりもバグを書きやすくします。


3
うわー、それはそのようなでたらめです。「正しいコードより」。どこかに行って。
ジョナサンスターリング

安全に使用するために余分なコードを記述する必要がある場合、私の本では間違った使い方をしやすいです。For ... inでは、プロトタイプのオブジェクトを繰り返し処理していないことを確認するために追加のチェックが必要です。foreachでは、後で参照をクリーンアップするか、配列の最後の値を上書きするリスクがあります。
ジョーリSebrechts

参照を変更するforeach(&演算子)は有名なバグです
...-umlcat

1
私は混乱しています。javascriptの「for..in」コンストラクトが壊れているのは常識だと思っていました...なぜこれが不快なのですか?
lvilnis

2

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


3
型を逆読みします。int[]*は整数int*[]の配列へのポインターであり、整数へのポインターの配列です。constsでもうまく機能します:int* constは整数への定数ポインターですが、const int*int const*は定数整数(または整数定数)へのポインターです。
zneak

@zneak:「右から左」は機能しません。前述の「時計回りのスパイラル」/「裏返し」ルールを参照してください。

または、typedefを使用するだけで混乱はありません。
ビリーONeal

最新のC ++では、ポインターと配列はほとんど必要ありません。
fredoverflow

4
@tchrist:違います。10のintの配列へのポインタであることをint (*p)[10];宣言pします。場合はsizeof (int) == 4、その後、p++進めるp40で
j_random_hacker


1

Javascript / Javaなど、比較と等しい、例えばif(a == 1)

if(a = 1)を何回書きますか?

私は人間としてそれを完全に読みました。しかし、インタープリター/コンパイラーは、「aに1を割り当ててから、aが1に等しいかどうかを確認し、そうだと信じますか!」と言います。

私を壁に追いやる。

if(a == 1)ははるかに読みにくく、インタプリタ/コンパイラはとにかく私が何を意味するかを知っているはずです。他の多くの下位言語(VB)は何百年もの間、うまく機能してきました。


どういうif (a = true)意味ですか?
トムホーティン-タックライン

2
割り当ては値を返すだけではいけません。それは時々有用ですが、ほとんどの場合、それはただ首の痛みです。
コンフィギュレー

Javascriptでは、JSLintがそれをキャッチします。
ザカリーK

問題は、条件の割り当てが役立つ場合があることです。<tt> while(element = list-> next())</ tt>は非常に読みやすいと思います。そのため、削除してもらえるかどうかわかりません。
インカ

3
@Tom:ブール値が理解できないことを意味します。あなたが意味するならif (a == true)、書いてくださいif (a)。を意味する場合a = trueifステートメントは冗長です。
dan04


0

structPointer->memberC / C ++で。他の人のコードを読むのに良いかもしれませんが、私はそれが好きではありません。1人ではなく2人のキャラクター...スペースの無駄だ!


2
残念ながら、これはから区別する必要があります.。これは、非ポインターオブジェクトのメンバーに適用されます。あいまいな構文は悪いですね、mmmkay?
greyfade

2
@greyfade:うん!コンパイラはできませんので、おそらくあなたは、ポインタ・ツー・構造体タイプを使用しているとき言うと、暗黙的に間接参照を適用するには、その型システムの規則を使用しています。いいえ、それはおかしな話です!(それでも、間違えるとエラーメッセージが表示される可能性があります。)構文に曖昧さはありません。いつものように、Cは脳死状態の混乱です。それは確かにパーサを混乱させずに行うことができますので、あなたが実際に...、ポインタ・ツー・レコードを必要と暗いコーナーで作業している場合Delphiは、うまく暗黙の逆参照を行います
メイソンウィーラー

5
@Mason:どのような場合についてのshared_ptr場合は、->含まれているタイプにアクセスして.のプロパティにアクセスshared_ptr自体を?申し訳ありませんが、ここではまったく同意しません。
ビリーONeal

2
悪化する可能性があります。PHPである可能性があります。ここで->は、何かのメンバーにアクセスするために使用する必要があります。
カーソンマイヤーズ

1
@maaartinus:操作の非自明な順序に大きく依存しているコードは、私が書いているコードではありません。
ビリーONeal

0

括弧内のScala複数行コード

例えば:

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

あなたが実際にそれから得るものは素晴らしいです。それはあなたのためにコンストラクタとゲッターとセッターを生成します。しかし、それは確かにく、コードをインデントする方法の私のすべての精神的なモデルを壊し、基本的に私は一方がJavaで他方がLispである奇妙なサンドイッチのように感じます。(ああ、待って...それがScalaのポイントです。)


私は混乱しています-あなたは括弧内の部分(val barなど)または中括弧内の部分(次の部分)を意味しますextends Modelか?(そのコードには括弧はありません)
ビリーONeal

3
括弧内の部分。私はイングランド人。その状況では、括弧で囲まれた役割を果たさないため、それらを括弧と呼びます。
トム・モリス

2
:この方法インデント場合、それはすべてが悪い見ていないpastebin.com/h9qC8XGg
missingfaktor

特にいくつかのパラメーターしか持っていない場合、これらのコンストラクターパラメーターリストを水平に記述する方が読みやすいと思います。
MJP

私には方法のように見えます。Simulaのように。古き良き学校。
トムホーティン-タックライン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.