どのプログラミング言語が最も見つけにくいバグを生成しますか?[閉まっている]


54

あなたの意見では、平均的なプログラマーが見つけにくいバグを最小限に抑えて機能を出力できる言語は何ですか?これはもちろん非常に広範な質問であり、私は非常に広く一般的な答えと知恵に興味があります。

個人的には、JavaおよびC#プログラムの奇妙なバグを探すのにほとんど時間を費やさず、C ++コードには明確な繰り返しバグのセットがあり、Python / similarにはコンパイラによって検出される一般的で愚かなバグのセットがあります他の言語で。

また、完全に機能的なコードで書かれた大きくて複雑なプログラムを見たことがないので、この点で関数型言語を検討するのは難しいと感じています。ご入力ください。

編集:見つけにくいバグを完全にarbitrary意的に明確化:再現するのに15分以上かかり、原因を見つけて修正するのに1時間以上かかります。

これが重複している場合はご容赦ください。ただし、この特定のトピックについては何も見つかりませんでした。


10
このトピックに関する研究をいくつか見たいです!「私の逸話的な証拠は、私が知っている唯一の言語が王様であることを示唆している」だけでなく、大規模プロジェクトのバグ率なども示しています。
フランクシェラー

@Frank .. A LOT(そして私がA LOTを意味します)の時間があった場合、何千ものコードリポジトリのバグを修正するパッチを特定できれば、おそらくohlohからいくつかの統計をマイニングできます。
ティムポスト

コメントのみが許可されるもの。他の指示はありません:)
ビクターHurdugaci

4
「見つけるのが難しい」ことを明確にする必要があると思います。あなたの質問とほとんどの答えは、「見つけるのが難しい」を「コンパイラに捕まらない」と同等であると定義しているようです。あなたは、Pythonがコンパイラによって検出される愚かなバグを持っていると言います。けっこうだ。しかし、これらの愚かなバグは通常それほど見つけるのは難しくありません。確かに、それらはメモリをすぐに解放すると言うC ++のバグと同じカテゴリにはありません。
ウィンストンイーバート

@ウィンストン同意する。
マグナスウルフフェルト

回答:


58

言語の型システムが強力であればあるほど、コンパイル時により多くのバグがキャッチされます。

次の図は、よく知られているプログラミング言語のいくつかを、型システムの能力、単純さ、および安全性の観点から比較しています。[ ソース ]

代替テキスト

*安全でない構成要素を使用する能力の要因。

「安全でない」キーワードと関連するポインター機構のために、C#は安全でない行に詰め込まれます。しかし、これらを一種のインラインの外部関数メカニズムと考えたい場合は、C#を空に向かって飛ばしてください。

Haskell '98を純粋であるとマークしましたが、GHC Haskellは関数の安全でない*ファミリーのために純粋ではないとマークしました。安全でない*を無効にすると、それに応じてGHC Haskellがジャンプアップします。


8
これは素晴らしいです!

7
私は、グラフィックにはCommon Lispを見つけることができませんでした。(let ((itbe '())) ... )...
DUROS

7
何?PHPの左側にスペースが残っていませんか?
ペスター

7
C#は安全なポインターを許可します。すべてのポインター演算がチェックされます。そのため、Javaを使用する必要があります。
アレックス10ブリンク10

11
@missingfaktor:C#は適切な位置にないと思います。C#は、safterプログラミングスタイルを許可および促進します。それが許す最悪のものによって測定されるべきではありません。
back2dos

20

私の意見では、Haskellは一般的なエラーの原因を回避するのに役立ちます。

  • それは純粋に機能的です:関数は(意図しない)副作用を持つことができません。これにより、マルチコアプログラミングが簡単になり、エラーが発生しにくくなります。
  • 強く型付けされています:たとえば、bool、char、int、floatの値を誤って混在させることはできません
  • 静的に型付けされている:コンパイル時に多くのプログラミングエラーがキャッチされる
  • null値型定義の一部ではありません:これにより、10億ドルの間違いを回避できます
  • 欠陥のある独自の実装を書く代わりに、再利用できる既製の高階関数がたくさんあります
  • ガベージコレクターがあります:メモリエラーはほとんど排除されます(遅延評価戦略による「スペースリーク」を除く)

11
私はこれに反対票を投じることはしませんが、基準に合わないために誘惑されます。「平均的なプログラマーは最小限のバグ数で「機能を出力する」ことができるはずですが、平均的なプログラマーは、率直に言って、そもそもHaskellの頭や尻尾を作ることはできません。
メイソンウィーラー

5
多くの良い点がありますが、いくつかのクラスのエラー(意図しない副作用、予期しない型変換)を削除する一方で、Haskellはまったく新しいクラスのエラー、スペースリークを追加します。(また、ありませんがnullundefinedすべてのタイプのメンバーであるがあります。)
j_random_hacker

5
@メイソン:あなたがそれを書いていない場合、あなたはそれをバグにすることはできません:)
マイケルK

2
無料のランチのようなものはないと思います-見つけやすいバグや書きやすいコードはありますが、両方はありません:)
Benjol

6
@Mason「平均的なプログラマー」とは正確には何ですか?質問は「どのプログラミング言語...」で始まり、「C、C ++、javaのどれか...」ではありません;)
Agos

18

従来、バグを見つけるのが最も難しいのは、マルチスレッドアプリケーションの競合状態です

  • ほぼ再現不可能
  • 非常に微妙になることがあります

したがって、あなたは、あなたのために、可能な限り邪魔にならないように、視差を管理する言語が必要です。これらはまだ主流ではありません。Javaはいくつかを行いますが、難しい部分はあなたに残します。

私の理解では、「副作用なし」はそもそも2つの箇条書きをなくすものなので、関数型言語が必要です。Haskellを透過的に効率的なマルチスレッド言語にする作業が進行中であり、Fortressは効率的な並列言語になるようにゼロから設計されていると思います。


編集:Javaでは、Executorsさらに多くの難しい部分を処理します。個々のタスクをCallableインターフェースに適合させる必要があります。


5
++競合状態。もう一度言うことができます。
マイクダンラベイ

うん。一般に並列コンピューティングは、言語支援があっても難しいことに留意してください。(一般的なLispマクロは、多くの言語サポートにもかかわらず、それらが行うことは非常に強力であるため困難です。同じ原則。)
デイヴィッドソーンリー

Erlangはどうですか?
マルフィスト

@Malfist、私はそれに答えるのにアーランについて十分に知りません。本当に知りたいのなら、質問を開くべきでしょうか?

2
Erlangは、マルチスレッドを簡単かつ安全にするために設計された関数型プログラミングです。変数を共有せず、メッセージを渡します。ウィキペディアのページを読んでください。
マルフィスト

13

Adaは、実行時ではなくコンパイル時に可能な限りキャッチされるように設計されています。これが意味することは、AdaのプログラムをコンパイルするのにJavaの同等のものよりもしばしば約10倍時間がかかることですが、コンパイルすると、プログラムのバグのクラス全体が現れないことをはるかに確信できます走る。


7
+1は、Adaが他の言語が無視するコンパイラーの内容をキャッチすることを正しく認識します。-1。これは、Adaプログラムをコンパイルするのに10倍時間がかかることを意味するという主張に対して。Adaは設計者のプログラマーに報酬を与えます!!! 彼のコードは誰だと思う!!! 彼が狂ったようにタイピングを始める前に彼が何をしているかについて。私の個人的な経験では、防衛作業のためにAdaでプロダクションプログラミングを行っていましたが、C / C ++またはFORTRANを使用するよりもAdaコードをコンパイルする方が大幅に長くかかりませんでしたが、後でAdaコードを使用した場合のトラブルは大幅に少なくなりました。プラット&ホイットニーは似たようなことに気づきました。
ジョンR.ストローム

1
@john r strohm、私が理解していることから、彼はコンパイラがコードをコンパイルするのにかかる時間ではなく、コードをコンパイル可能にする時間について話している。
マルフィスト

ああ、コードをコンパイル可能にすることに同意しました。私は、言語を学ぶために、そのつまらない選択についてプログラマーが行った性差別的なコメントをかなり覚えています。通常まあの線に沿って、あなたが女性の後の言語に名前を行う場合...
マイケル・ショー

@Ptolemy、ボートの名前が女性にちなんで付けられる場合(米国のキャリアを除く)、プログラミング言語も同様です。「USSロナルドレーガン」よりも「エイダ」という名前を付けてください:)

1
学習曲線を乗り越えた後、設計を熟考してかなりの時間を費やした後、実際にAdaコードを書くのがかなり速くなりました。Adaは、間違いなくハッカーの言語ではありません。私は最近Javaで働いており、現在のプロジェクトで見ているもののいくつかは、実際にAdaを少し恋しく思います(私はそれを言うとは思わなかった)。
ジェームズアダム

7

最初に定義:見つけにくいバグは、私が理解しているように、再現できるバグですが、原因を見つけるのは難しいです。

おそらく最も重要な側面は、私が「狭さ」と呼ぶもの、つまり、バグがどこまで逃げることができるか、バグが潜在的に影響を与える可能性のある範囲です。Cなどの言語では、負の配列インデックスや初期化されていないポインターなどのバグがプログラム全体の文字通りすべてに影響を与える可能性があるため、最悪の場合、問題の原因を見つけるためにすべてをチェックする必要があります。

その点で優れた言語はアクセス修飾子をサポートし、それらを迂回することを困難または不可能にする方法でそれらを実施します。優れた言語では、グローバル変数を持ちやすくするのではなく、変数のスコープを制限することをお勧めします(たとえば、「明示的に宣言されていないものはすべて、デフォルトの型と値を持つグローバル変数」)。

2番目の重要な側面は並行性です。競合状態は一般に再現が難しく、したがって見つけるのは困難です。優れた言語は使いやすい同期メカニズムを提供し、その標準ライブラリは必要に応じてスレッドセーフです。

これですでにリストが完成しました。強力なタイピングのような他のものは、コンパイル時にバグをキャッチするのに役立ちますが、それらのバグはおそらく後で見つけるのは難しくないでしょう。

これらすべてを考慮すると、JavaとC#、およびJVMと.netの世界の他の多くの言語は、見つけにくいバグを回避するのに適していると思います。


手動ロックは「使いやすい同期メカニズム」のように見えるかもしれませんが、実際には「簡単に使用できますが、そのデッドロックを追いかけて楽しい時間を過ごすことができます」。そして、まあ、かなりの数の言語でアクターベースの並行処理を行うことができます。
フランクシェラー

フランクは:少なくともロックは、誰もが日を費やすことなく、それを行うことができますので、十分に単純である、などに使用するAPIを考え出す
user281377

そして、「誰でもできるほど簡単」な同時実行ソリューションは、未就学児にテーブルソーを与えるようなものだという見方があります。
デヴィッドソーンリー

@David:あなたの主張はわかりますが、多くの場合、単純な解決策で十分です。たとえば、共有リソース(データベース接続など)を使用する必要がある少数のユーザーのみが使用するサーブレットを考えてみましょう。同期を行わないと、競合状態が時々発生します。しかし、すべてのデータベースアクセス操作をsynchronized(connection){}ブロックに入れるのは、まさにロケット科学ではありません。
user281377

+1この定義では、「バグが影響を与える可能性のある範囲の大きさ」。動的な言語には非常に厄介なバグがあり、バグとして現れる前に、間違ったデータ型のオブジェクトがコード内で非常に遠くまで到達しました(アヒルの入力のおかげ)。
ジョルジオ

7

Excelは最も広く使用されているDSLなので、Excelを使用します。(もちろんVBAを除く)

法案に適合:

  • いつでも簡単に再現できます(ここにスプレッドシートがあります-動作していません)
  • バグは完全に「機能」しているため、見つけるのは非常に簡単です-間違っているセルから始めて、すべての依存関係をトレースバックします。

これは、見つけやすいバグを追加しない限り当てはまります。
ムーヴィシエル

+1 Excelはデータであり、言語ではないため、少し生意気です。私に良い笑いを与えた:)
recursion.ninja 14

2
@awashburn-ああ、わからない。言語としての資格があると思います。各セルは「変数」です。各変数は、リテラル(123またはなどABC)または関数(=SUM(A2:A5))として宣言的に設定されます。次に、Excelはすべての変数を評価し、依存関係を解決する順序などを決定します。これは確かに単なるデータではありません。
スコットホイットロック14

2
私は私の声明を撤回、それはExcelがチューリング完全であることを判明...私は...完全に不安何かを学んだ
recursion.ninja

1
「...真の[Lisp]マスターは、すべてのデータがコードであることを認識しています。」おそらく、これはExcelにも当てはまります。blogs.msdn.com/b/sriram/archive/2006/01/15/lisp-is-sin.aspx
ジェームズミシュラ

7

ほとんどのバグは言語自体のせいではなく、開発者が言語の使い方を間違えたせいだからです。

バグの可能性に影響する言語機能にはいくつかの側面があると思います。

  • 対話性 -REPLを使用した動的言語は、実行中のプログラムとはるかに短いコード/テストサイクルでの対話/実験を促進します。イテレーションがクリーンでシンプルなソリューションを発見し、バグを検出/除去する良い方法であると信じるなら、これはインタラクティブ言語を好む傾向があります。

  • 表現力 -コードが短く、定型的/偶発的な複雑さが少ない場合、バグ/論理エラーが見やすくなります。

  • 型の安全性 -コンパイル時間のチェックが多いほど、コンパイラによって検出されるバグが増えるため、一般的に型の安全性は良いことです。しかし、これらは通常、バグを見つけるの難しくありません。完全に動的な言語であっても、データ構造の間違った型は通常非常に明白な実行時エラーを引き起こします。

  • 不変性 -多くのハードバグは、可変状態の複雑な相互作用によるものです。不変性を強調する言語(Haskell、Clojure、Erlang)には、不変性を回避することで大きな利点があります

  • 関数型プログラミング -コードを記述するための関数型アプローチは、効果/相互作用の複雑なシーケンスを持つオブジェクト指向のコードよりも「証明可能に正しい」傾向があります。私の経験では、FPはトリッキーなバグを回避するのに役立ちます。これを裏付ける学術研究はどこかにあると思います。

  • 同時実行性のサポート -同時実行性の問題の検出とデバッグは特に難しいため、これが非常に重要です。手動ロックが必要なものはすべて最終的に失敗する運命にあります(これには、並行性に対するほとんどすべてのオブジェクト指向のアプローチが含まれます)。この点で私が知っている最高の言語はClojureです。ソフトウェアトランザクションメモリと不変のデータ構造を組み合わせて、並行性を管理する独自のアプローチがあり、新しく、信頼性が高く、構成可能な並行性フレームワークを取得します。詳細については、http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickeyをご覧ください


関数型プログラミングの情熱的なサポーターである私のような人々は、この答えを高く評価しています。表現力はあなたの友人です。
スリダールサルノバト

1
これまでのベストアンサー!これは、バグの頻度に関する次の2つの分析、deliberate-software.com / safety-rank-part- 2 とmacbeth.cs.ucdavis.edu/lang_study.pdfによって裏付けられていると思います。どちらも、言語が純粋で、機能的で、表現力があり、安全であるほど、バグが少ないことを示しています。同様に、どちらもClojureとRubyがSafetyルールを免れていることを示しており、おそらく指摘したとおり、Interactivityの影響は同等であることを示しています。
ディディエA.

@DidierA。残念ながらucdavisリンクは(無WBMのアーカイブで)壊れている-私はあなたからそれを得たと思うプレムDevanbuのページになりました更新されたリンクを指す:Githubのでのプログラミング言語とコード品質の大規模研究
icc97

5

言語の能力が低いほど、自分の足を撃つための選択肢が少なくなります。

JavaやC#のような高レベル言語は、C ++のような低レベル言語よりもバグが少なくなります。

JavaはC#よりも安全であると信じています。Javaは人為的に制限されているため、高度な知識のない平均的なプログラマーがJavaを習得し、安定したプログラムを作成できます。


4
「言語の能力が低いほど、自分の足を撃つための選択肢が少なくなります。」の+1
マイケルK

missingfaktorのグラフは、C#とC ++が同じ「足場」にいると言っているようです。ただし、チャートのその部分に同意するわけではありません。いくつかのC#シューティングを行うには、フープを通過する必要があります。
ジェシーC.スライサー

6
安全性とパワーは反比例していません(これはあなたが考えるようです;-)たとえば、Haskellは非常に強力ですが、自分で足を撃つ方法はほとんどありません。
missingfaktor

3
言語が弱い場合は、より大きな足が必要です。

7
@missingfaktor、それは足で自分を撃つことが副作用だからです。

3

あなたの意見では、平均的なプログラマーが見つけにくいバグを最小限に抑えて機能を出力できる言語は何ですか?

私の意見では、Delphi。Pascalに基づいているため、この言語はシンプルで直感的であり、平均的なプログラマー(または経験の浅いコーダー)でも簡単に理解できます。また、その豊富なツールとライブラリのサポートにより、ほとんどのバグを簡単に見つけることができます。

  • 強い型付けと、多くの一般的なエラーをキャッチする厳密なコンパイラ。
  • 一般的なエラーを助長しない直感的な構文。(if (alert = RED) {LaunchNukes;}たとえば、「The World's Last Bug」はコンパイルされません。)
  • 一般的なC ++ OOPエラーの多くを排除する、適切に設計されたオブジェクトモデル。
  • 言語に組み込まれた境界チェックと範囲チェックにより、セキュリティ上の問題が発生する可能性が大幅に減少します。
  • おそらく、人間に知られている最速のコンパイラーです。これにより、生産性が向上し、ビルドの待機中に思考の流れが失われにくくなります。
  • デバッガーVisual Studioのデバッガーは、成長したときのようになりたいと考えています。
  • リークトラッキングはメモリマネージャに直接組み込まれているため、メモリリークの発見と修正は簡単です。
  • 独自の、おそらくバグのある実装を構築することなく、一般的なタスクを実行するための事前構築および事前テスト済みの方法を提供する、大規模で成熟した標準ライブラリ。
  • 強力なロギングシステムやプロファイラーなどの便利なツールが同梱されており、問題を簡単に追跡できます。
  • 強力なサードパーティの同時実行ライブラリなど、標準ライブラリにはない一般的な問題に対する強力なコミュニティサポート。

私は戻って道からDelphiのジョッキーだが、それはパスカル根をだから、それは私が何か、ラ・C / C ++には何を型キャストすることができたときにそれが去っていきました:var I: Integer; Pointer(I)^ := $00;
ジェシーC.スライサー

1
@Jesse:おそらく、しかし、私はそれをプラグマティズムに必要な譲歩として見ています。Kernighanは、Pascalが私のお気に入りのプログラミング言語ではない理由を書いたときに多くの良い点を指摘しました タイプキャストは、多くの重要な低レベルの処理を実行するために必要です。しかし、Delphiの強みの1つは、そのライブラリが低レベルの詳細をカプセル化し、安全でないポインターと型キャストのほとんどを不要にする方法です。
メイソンウィーラー

私はそれが必要かもしれないことに同意しません-しかし、これによりストロングタイピングを主張することは幾分否定されます。オリジナルのパスカルはそのようなシェナンガンを許可しなかったため、強くタイプされました。しかし、私はこれまでのところ、Delphiを弱い型付けと呼ぶつもりはありません。これは一種の「中型の型付け」です。
ジェシーC.スライサー

1
@Jesse:オリジナルのWirthバージョンのPascalではバリアントレコードが許可されていませんでしたか?IIRCは、最終的に強力なタイピングを破壊するために非常に一般的に使用されるようになったため、Borlandなどは、誰もがやっていることでタイプキャストを単純化することにしました。
メイソンウィーラー

en.wikipedia.org/wiki/Pascal_(programming_language)#Divisionsen.wikipedia.org/wiki/Pascal_(programming_language)#Criticismなどpascal-central.com/ppl/chapter3.htmlそれを示すように見えるがの一部でした1983年の最初の標準。1974年に作成されたと思われるWirthの参考文献がいくつかあります。問題のある部分は、それをそのように破壊することを許可していたと思います(つまり、Cの共用体のように、同じメモリを使用するバリアントフィールド)。スコーピングメカニズムとして単純に使用され、メモリレイアウトがスーパーセット用である場合、より強力に型付けされます。
ジェシーC.スライサー

2

考慮すべきことの1つは、所要時間です。

過去5年ほどの間、私は主にJava(JSF、Seamなど)でWebアプリケーションを開発しました。最近、私は新しい仕事を得て、私たちはPerl(CatalystとMooseを使用)を使用しています。

私はJavaのときよりもPerlのほうがずっと生産的です。

コンパイルおよび(ホット)デプロイする必要がないことが1つの理由です。また、ユースケースの作成がより反復的な方法で行えるため、作成が簡単であることがわかりました。Javaのフレームワークは、少なくとも私が関与しているプロジェクトにとっては、不必要に複雑なようです。

私のPerlコードのバグの数は、Javaコードのバグの数とほぼ同じですが、それよりも多いかもしれません。しかし、これらのバグを見つけて修正する方が簡単で迅速です。


1

おそらく、すべてのプログラミング言語の静的および動的コード分析に使用可能なツールの数を調査すると、アイデアが得られる可能性があります。言語用のツールが増えれば増えるほど、その言語はユーザーに非常に人気があるか、見つけにくいバグを生成するのに非常に人気があります。しかし、このテーマに関する研究をGoogleに指摘することはできません。また、Cなどの一部の言語を使用して、基礎となるハードウェアのバグを回避したり、ハードウェアの経年変化による摩耗を回避したりすることもできます。


1
「経年変化に伴うハードウェアの消耗を回避する」...?
j_random_hacker

私は、ミッションクリティカルなマシンで実行される一部のUnix OSがCPU、RAM、およびその他のハードウェアの状態をチェックすることを読みました。 serverfault.com/questions/56192/…でこれについて詳細に説明しています。RAMモジュールの一部のラインが時間の経過とともに障害を起こした場合、それらの障害のあるモジュールはOSによって使用されず、利用可能な物理メモリの合計でそれらを報告しません。このようなことは、他のハードウェアでも実行できます。
vpit3833

これは興味深い話ですが、ここでどのように関連するのかわかりません。また、リンクの中でこれらの自己修復Unix OSについて言及しているものはありません。PCのハードウェアのストレステストを行う方法についてのみ言及しています。
j_random_hacker

1
プログラムだけがバグの原因ではなく、ハードウェアやその他の外部要因でもある可能性があることを意味すると述べました。
vpit3833

1

言語について話す代わりに、言語機能について話すことについて

  • javaは例外について考えるように強制します(スロー...)。これらの例外を公開するか、処理する必要があります。それは本当にエラー状況を忘れることを防ぎますか、この処理を必要としないSystemExceptionから派生したより多くの例外を使用していますか?
  • 「契約による設計」(http://en.wikipedia.org/wiki/Design_by_contract)についてはどうでしょうか。事前条件と事後条件について考えるように強制されます。私はc#-4.0で可能になったことを読みました。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.