web-dev-qa-db-ja.com

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

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

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

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

編集:見つけにくいバグの完全に任意の説明:再現に15分以上、または原因の特定と修正に1時間以上かかります。

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

54
Magnus Wolffelt

言語の型システムが強力であるほど、コンパイル時にバグが捕捉されます。

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

alt text

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

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

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

58
missingfaktor

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

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

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

  • 再現がほとんど不可能
  • 非常に微妙な場合があります

したがって、できるだけ多くの邪魔にならないように視差を管理する言語が必要です。これらはまだ主流ではありません。 Javaは一部を実行しますが、難しい部分はそのままにします。

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


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

18
user1249

Adaは、実行時ではなくコンパイル時に可能な限り捕捉されるように設計されています。これが意味することは、Adaでプログラムをコンパイルするのに、相当するJavaの場合よりも)を実行するのに約10倍長くかかることですが、コンパイルすると、クラス全体がはるかに自信を持つことができますプログラムの実行時に、バグの多くは現れません。

13
Mark Pim

まず定義:見つけにくいバグは、私が理解しているように、再現可能なバグですが、原因を見つけるのは困難です。

おそらく最も重要な側面は、私がnarrownessと呼ぶものです。つまり、バグがどれだけ遠くまでエスケープできるか、バグが影響を与える可能性のある範囲はどれほど大きいかです。 Cのような言語では、バグ。負の配列インデックスまたは初期化されていないポインタは、プログラム全体のあらゆる場所に文字通り影響を与える可能性があるため、最悪の場合、すべての場所を確認する必要がありますすべてを確認する必要がありますあなたの問題の原因。

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

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

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

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

7
user281377

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

それは法案に適合します:

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

ほとんどのバグは言語自体のせいではないため、これは難しい質問です。むしろ、開発者が言語の使い方を間違えているのはバグです。

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

  • Interactivity-REPLを使用した動的言語は、実行中のプログラムの相互作用/実験と、はるかに小さなコード/テストサイクルを促進します。反復がクリーンでシンプルなソリューションを発見し、バグを検出/排除するための良い方法であると信じるなら、これはインタラクティブ言語を支持する傾向があります。

  • 表現力-コードが短く、ボイラープレート/付随的な複雑さが少ない場合、バグ/ロジックエラーが見やすくなります。

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

  • 不変性-多くのハードバグは、可変状態の複雑な相互作用が原因です。不変性を強調する言語(Haskell、Clojure、Erlang)は、変異性を回避することによって非常に有利です。

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

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

7
mikera

言語が強力でないほど、自分の足を撃つためのオプションが少なくなります。

JavaやC#などの高水準言語は、C++などの低水準言語よりもバグが少なくなります。

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

5
user8685

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

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

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

考慮すべきことの1つは、時間の方向転換です。

過去5年間、私は主にJava(JSF、Seamなど)でWebアプリケーションを開発してきました。最近、新しい仕事を得て、Perl(with触媒とムース)。

Perlの方がJavaの場合よりもずっと生産的です。

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

私のPerlコードのバグの数は、多かれ少なかれ、私のJavaコードのバグの数と同じです。それよりも多いかもしれません。しかし、これらのバグを見つけて修正します。

2
slu

おそらく、すべてのプログラミング言語の静的および動的コード分析に使用できるツールの数を調査することで、アイデアが得られるでしょう。言語用のツールが多いほど、その言語はユーザーの間で非常に人気があるか、見つけにくいバグを生成する上で非常に人気があるかのどちらかである可能性が高くなります。しかし、私はこの点について行われたいかなる調査についてもGoogleに指摘させることができません。また、Cなどの一部の言語は、ハードウェアのバグを回避したり、ハードウェアの経年劣化を回避したりするために使用できます。

1
vpit3833

言語について話すのではなく、言語機能について話すことについて

  • Javaは例外(throw ...)について考えることを強制し、publischまたはこれらの例外を処理する必要があります。それは本当に私がエラー状況を忘れることを防ぐのですか、またはこの処理を必要としないSystemExceptionから派生したより多くの例外を使用していますか?
  • 「契約による設計」(http://en.wikipedia.org/wiki/Design_by_contract)では、事前条件と事後条件について考える必要があります。私はそれがc#-4.0で可能になったことを読みました。
1
k3b