プログラミング言語の冗長性について文句を言う人がたくさんいます。プログラミング言語の冗長性が高いほど、理解するのが適切であることがわかります。冗長性はAPI
、その特定の言語のより明確なsの作成も強化すると思います。
私が考えることができる唯一の不利な点は、より多くの入力ができることですが、ほとんどの人がすべての作業を行うIDEを使用しているということです。
それでは、冗長プログラミング言語の潜在的な欠点は何ですか?
プログラミング言語の冗長性について文句を言う人がたくさんいます。プログラミング言語の冗長性が高いほど、理解するのが適切であることがわかります。冗長性はAPI
、その特定の言語のより明確なsの作成も強化すると思います。
私が考えることができる唯一の不利な点は、より多くの入力ができることですが、ほとんどの人がすべての作業を行うIDEを使用しているということです。
それでは、冗長プログラミング言語の潜在的な欠点は何ですか?
回答:
「冗長」とは「使用する単語が多すぎる」という意味です。問題は「多すぎる」ことです。
良いコードは一目で理解しやすいものでなければなりません。これは、ほとんどの文字がコードの目的を直接果たす場合に簡単です。
場合は言語が冗長である、あなたのコードのよりはノイズです。Javaの「Hello World」を比較します。
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
... Rubyの場合:
print "Hello World!"
騒音は精神的なエネルギーを浪費します。
一方で、言語の過度の簡潔さも精神的エネルギーを犠牲にします。Common Lispからのこれら2つの例を比較してください:
(car '(1 2 3)) # 3 characters whose meaning must be memorized
# vs
(first '(1 2 3)) # 5 characters whose meaning is obvious
一目で表示および解析できるコードの量に影響します
x++
のではなく set(x,Integeradd(get(x),1))
追伸 コードを読むだけの問題ではありません。40x25のスクリーンの時代には、APLタイプの言語、またはPerlは、CobolやFortranよりも読み取り/ページ化できるコードの量が多いため便利でした。しかし、今ではあなた自身の内部キャッシュについてです-ステートメントが単一の演算子を持っている場合、3つのシンボルと4つの関数呼び出しを持つものよりも私の老化した脳が解析しやすいです。
set
メソッドはここで何をしますか?実際に何かを設定していますか(つまり、最初のx
パラメーター)、それとも何かを返していますか(x
呼び出し後の割り当て)。詳細な例では、奇妙な重複が起こっていると思います。
+
、の場合よりも意味がありplus
ます。 =
よりも優れていequals
ます。もちろん、これはあまりにも遠すぎます(いくつかの言語で行われています)が、適度に使用すると非常に強力です。
言語の冗長性がコードの可読性を損なう場合、それは悪いことです。
一部の言語には、コードの意味を把握するのに時間がかかるような冗長な構文があります(VB.NETとC#を考えています)。
If something Then
End If
if(something)
{}
要するに、コーダーがなじみやすく快適なものです。
If .. Then .. End If
重要なことだけを読みます。
見に行くのAppleScript、私はそれをオフ考えることができる最も詳細な言語の一つは、考えることができ、現在、しようtrival何かを書くことにして戻ってきて、試してみて、冗長性は、言語では良い形質であると主張しています。
キーワードがどこに行くのか、それらが何であるのかという意味をすべて覚えようとするのは、毎日やらなければ簡単ではありません。
この些細な例のすべてのキーワードノイズを見てください:
tell application "Finder"
if folder "Applications" of startup disk exists then
return count files in folder "Applications" of startup disk
else
return 0
end if
end tell
bash
従来のUnixツールでは同じことは簡単ですが、ほとんどのOSXユーザーにとっては不可解であるため、バランスを取る必要があります。
return the 0
をタイプしたときにしたくありませんでしたか?AppleScriptは、私が知っている唯一の言語であり、あなたの敵対者をキーワードでグリーフィングすることができます...私は同僚を意味します。
私はあなたがその質問に頭を向けて尋ねる必要があると思う:なぜ一部の人々は簡潔なコードが良いと思うのか?
私の答えは、2つの基本的な理由があるということです。
Terseの方が良い理由
これらには、短い文章が花のような冗長な文章よりも理解しやすいのと同じように、より読みやすいことが含まれます。多くの場合、英語の文法をエミュレートしようとするプログラミング言語は恐ろしく長引き、最終的に最も単純なアクションを実行するために膨大なコードを必要とします。多くの場合、言語が書かれた言語をエミュレートするほど、論理的に複雑な操作を実行するのが難しくなることがわかります。
Terseが悪化する理由
一部の言語(およびPerlのことを考えている)は、構文の一部として、ほとんど任意に選択されたように見える奇妙な記号の配列を使用します。これらの象形文字に精通していない人にとっては、言語は突き通せなくなります。また、簡単に見られないタイプミスを犯しやすくなります。正規表現は、おそらくこの種の簡潔さの典型です。
また、率直に言って、簡潔なコードを書くことで自慢したい人もいます。これはStackOverflowで時々見られます。人々は読みやすさを犠牲にして非常にコンパクトな回答を提出することがよくあります。これは一種の「仲間に感銘を与える」哲学の知識ですが、優秀なプログラマーは「コードゴルフ」は保守可能なソフトウェアを作成する方法ではないことを認識しています。
terse
反意語verbose
(またはその逆)がありません。/アヒル
@frowing、私は、冗長性の問題を見るための1つの方法は、プログラミングは常に、解決策を見つけて表現する2つのかなり異なるスタイルの混合であることに気付くことをお勧めします。
最初のより詳細なスタイルは、言語指向(言語)プログラミングです。このスタイルは、文のような構造内で名詞のような単語と動詞のような単語を組み合わせたものであり、よく書かれた段落とほぼ同じ方法で読まれ、理解されることを意図しています。言語自体は普遍的であるため、言語プログラミングは最も普遍的なプログラミングスタイルです。同じ理由で、新しいプログラマが最初に探すのは、何が行われているのかを概念的に理解することなので、長期的なプログラムサポートには常に強力な言語コンポーネントが必要です。一般的なルールとして、プログラムを作成したコンテキストから離れるほど、言語スタイルのプログラミングは、コードを理解しようとする次の人があなたの仮定や概念を誤解しないようにするためにより重要になります。
2番目のより簡潔なスタイルは、数学指向(数学)プログラミングです。たとえば、変数は名詞や動詞の演算子に似ているため、このスタイルの推論も言語に依存しています。しかし、数学的推論は、脳の驚くほど高度な並列能力を活用して、視線内にあるオブジェクトに対して複雑な空間変換を行います。名詞と動詞をコンパクトで特徴的なシンボルとして表現することで、よく構造化された架空のオブジェクト(方程式)に配置できるようになり、高度な並列視覚機能を使用して、これらの架空の回転、置換、移動、反転、およびその他の変換を実行できますオブジェクト。その結果、各シンボルは密接に関連するオブジェクトのクラス全体を表すことができるため、一度に処理できるケースの数が大幅に増加します。
視覚処理を効果的に適用するには、仮想オブジェクトのサイズと機能を実際のオブジェクトとできるだけ同じにする必要があります。必要な視野が広すぎる場合、またはシンボルをオブジェクト上の可動マークのように使用できない場合、または「文字を読み取って」単語に変換する必要がある場合、複雑な変換を確実に実行する機能が低下します非常に優秀な数学者でもすぐに。
そのため、数学的スタイルのプログラミングに深く没頭している人は、方程式を広げて「冗長な」言語スタイルと呼ぶもので表現すると、非常に不幸になる可能性があります。方程式が大幅に変更されたからではなく、そのようにそれを広げると、視覚的な理解スタイルを適用することがほぼ不可能になるからです。同時に、短い記号にまったく精通していない新しいプログラマーは、コードが何をするのかを最初に理解するためにより多くの言語情報を提供するより冗長なバージョンを好む可能性があります。
だから私は何をお勧めしますか?
両方のスタイルを使用しますが、各スタイルを使用する理由に注意してください。
たとえば、コードと混在するインラインコメントの形式であっても、外の世界とやり取りする可能性のあるものは、何らかのレベルで集中的に冗長にする必要があり、正しい使用法の自動チェックも含める必要があります。不可解な、特に不完全に定義された表記法は、ある時点で誤解されることがほぼ確実であるため、そのようなインターフェースには関係ありません。火星気候Obiter 1999の損失によるソフトウェア・インターフェース・ユニットはポンドまたはニュートンで発現させたかどうかを認識する障害には、ソフトウェアまたはハードウェアインターフェースで生番号にすぎ何気なく頼るの危険の特に尖った例です。
逆に、本質的に深くアルゴリズム的で数学的なプログラミングの形式は、数学スタイルの推論をサポートする簡潔なプログラミングの優れた候補です。新しい人がそのようなコードを保守する必要がある場合、通常、コードをより冗長な形式に変換しようとするのではなく、数学表記を学習する方がよいでしょう。もちろん、そのような開発者が利用できるコードの数学的な部分を説明するために、いつでも簡単に利用できるドキュメントがあるはずですが、それは別の問題です。
これらの両極端の間に、プログラマーがかなりの裁量権を持っている多くのケースがあります。長期的にコードを維持する方法を検討し、長期的にコードを維持する可能性が最も高い人々のニーズに対応しようとすることをお勧めします。
多くの人が、おそらく明示的に述べられるべきだと思うことを示唆しています。
冗長性は、顕微鏡レベルでの理解を促進する傾向があります。一般的に、個々のステートメントが読みやすく、理解しやすくなります。また、冗長性は、それを理解するために必要な言語の習熟度を(少なくともある程度まで)低下させる傾向があります。最も詳細な言語(例:COBOL)は、完全な非プログラマーでも少なくともある程度読みやすくすることができます。
簡潔さは反対に向かう傾向があります。特に、特定の言語に最も精通しているプログラマーにとって、マクロレベルでの理解に役立ちます。同時に、その特定の言語に精通していないと、経験の浅いプログラマーであっても、初歩的な理解すら妨げる可能性があります。
そのため、読みやすさは対象読者によって大きく異なります。一方では、そのプロジェクトでほぼ独占的に働いている人々によって書かれ、維持されている大規模で複雑なプロジェクトを考えてください。これは、より簡潔な言語を好む傾向があります。
多かれ少なかれ反対の極端な場合、ソフトウェア自体ではなく、ソフトウェアに関連するビジネスを本当に専門とする人々によって主に維持されている、かなり単純な(おそらくかなり大きい)プロジェクトを検討してください。これはほぼ確実に、より冗長な言語を支持します。
技術書に行くのではなく、Strunk and WhiteのElements of Style * に戻ります。根底にあるコンセプトは「正確に」と「必要以上に発言しない」です。それ以外はすべて解説です。
プログラミングに適用されるのは、非常に正確であることですが、不要な毛羽立ちはありません。余分な綿毛は構文である場合もありますが、意味を伝えるために必要な数よりも多くの単語である場合もあります。(もちろん、曖昧さを許すには少なすぎません)
一日の終わりに、「異なる」ものは何でも人々を遠howえさせます。私はCスタイルの構文に慣れているため、同様の構文(C ++、Java、C#)を共有する他の言語でも問題ありません。だから私はこの特定のスタイルを好む傾向があります。
言語は、説明的なものと冗長なものとのバランスをとる傾向があります。
Perlは、非常に簡潔なコードを記述できる場所の例です。初心者にとっては、Perl忍者によって書かれたコードは魔法にほかなりません。
COBOLは冗長すぎる例です。
かつてどこかで読んだことですが、多くの冗長な議論は新しいプログラマーと古い手から来ています。類推は、何か新しいことを学ぶとき、それを乗り越えるための「物語」を自分自身に伝えるということでした(HSで代数を学んだときを考えてください)。経験を積むにつれて、個々のコンポーネントを説明するストーリーの必要性を超えて、より多くのことを理解します。私たちのコードは、コードが言っていることを繰り返すのではなく、必要な項目のみを説明するコメントで、より密度が高く簡潔になります。
私と同僚の間でこれが真実であることがわかりました。彼女は、コードの行が何であるかを説明するたくさんのコメントとたくさんの空白でコードを書きます。私がそれを読んでいるなら、私はこのために1つの画面に数行のコードしか適合できないことがわかります。これにより、個々の行を理解するのがはるかに簡単になりますが、関数全体を理解するのはずっと難しくなります。
私は余分な空白やコメントなしでコードを書く傾向があります。これにより、全体がはるかに見やすくなりますが、個々のコード「単語」を単純に「取得」できなければなりません。空白/コメント/余分な言葉遣いがたくさんある各単語を独自の行に入れてこの答えを読もうとすると、個々の単語を理解するのははるかに簡単ですが、全体を理解するのははるかに困難になります。
i++; //this is adding one to var i
それは冗長です。
アインシュタインは、「物事を可能な限り単純化するが、単純化するのではない」と正解した。
これはコードにも当てはまります。反復的で不必要に冗長な要素を削除してコードを簡素化できる場合、それは良いことです。
また、一部のケーススタディでは、コードの行で測定されるプログラマの生産性はほぼ一定であることが示唆されています。LOCごとのバグの数も同様です。したがって、他のすべての条件が同じであれば、コードの行ごとにより多くのことができる言語に切り替えることは生産性の向上と見なすことができます。
そうは言っても、この業界では単純なものを過剰に設計し、複雑にする傾向があります。リレーショナルデータベースに連絡先の詳細を詰め込むような単純なこと。その特定の問題に対して、とんでもないほど複雑で見当違いのソリューション(咳 MDA)を見てきました。ScalaやRubyのような言語は強力なツールの好例であり、特定の個人の手に渡ると、わかりにくく、過度に複雑で、保守が不十分なコードになります。いくつかのキーストロークで複数レベルの間接参照を使用できるからといって、その特定のハンマーを使用して、すべての釘を目の当たりにする必要はありません。
適切に使用すると、簡潔で理解しやすいきれいなコードが得られます。使用が不十分な場合は、問題の個人を視覚的基本言語または同様に制限された言語を使用して、さらなる被害を防ぐことをお勧めします。
真のスキルは、単純なものを複雑な方法で作成するのではなく、単純な方法で複雑なものを作成することにあります。
誰もヒットしなかったのは、1つの画面に収まるコードの量です。これにはいくつかの理由があります。
コードが増えると開発時間が長くなり、バグが増えるからです。
300行のコードではなく100行のコードを記述する場合。つまり、必要な開発時間はほぼ3分の1であり、発生する可能性のある潜在的なバグは1/3です。
ほとんどの場合、コードの記述が少なくなると、マシンはより多くのことを行う必要があり、効率が低下するため、効率と簡潔さのバランスを取る必要があります。
通常、人々は不可解な/簡潔な言語よりも読みやすい/冗長な言語を好みます。しかし、私はほとんどの人が「冗長性」と「クラッタ」を同化したと思います。
例えば: while(<>){print if($.==2 || $& && !$x++); $.=0 if (/^--+$/)}
非常に簡潔な文です。知りたいことすべてが含まれています。ただし、簡潔であるため、理解するのは困難です。一方、同じプログラムのもう少し冗長なバージョンは、読みやすいため、理解するのはかなり簡単です。もちろん、これは言語自体の特性ではありませんが、プログラミングの方法がより簡潔になる傾向がある言語もあれば、より簡潔にする傾向がある言語もあります。
冗長性のもう1つの極端な例はhttp://en.wikipedia.org/wiki/Literate_programmingです。 これは非常に興味深い概念であると考えています。
もう1つの側面は「不要な冗長性」で、「クラッター」とも呼ばれます。技術的な理由、構文糖の欠如、肥大化したAPIなどのために追加する必要があるもの。
明確で直感的な構文が非常に重要だと思います。また、読みやすくするのに十分な冗長性が必要です。あまりにも多くのロジックが詰め込まれた短い文では、多くの場合、わずかに長い対応文よりも解読に時間がかかります。一方、まったく単純なことをするためのボイラープレート行でいっぱいの無駄な肥大化コードは、同様に迷惑です。
冗長性は大量のテキストを使用する傾向であり、Tersenessは非常に少量のテキストを使用する傾向があります...
次の理由により、冗長性が悪い:
ただし、明確にするためにはある程度の冗長性が不可欠です...
次の理由から、最低限のレベルの詳細度が適しています。
多くの人々のために過度に簡潔なコマンドのいくつかの素晴らしい例は、古いBASICのスタンバイ含めるval(x$)
、str$(x)
とchr$(x)
...は、その文字列表現から数値を返す数の文字列を返し、文字列としてASCII値xを有する単一の文字を返します。
または、C / C ++ポインターおよび参照演算子によって&
、および*
BASIC byref
キーワードに対して。C / C ++では、変数Xを使用して、その変数へのポインターを渡すことができますが、どちらがポインターであり、どちらが「ポインターが指す変数として使用するか」を覚えておく必要があります。基本的には、関数呼び出しでbyrefキーワードを使用して参照を渡すだけです。これはより明確ですが、柔軟性が低くなります。
def fn Foo(x byref as float) foo= (x += x+1)
...
Foo(x)
このコードでは、byrefフラグによりxの内容が変更されます。一部のフレーバーは呼び出し時にbyrefを許可し、他のフレーバーは定義で、一部はどちらかで許可します。
冗長性は、カジュアルなプログラマがシンボリズムを簡単に使用できるようにするために重要です。BASICまたはpythonは、C / C ++よりも人間が読みやすく、詳細であるため、カジュアルなプログラマにとってははるかに便利です。C / C ++の簡潔さは、より多くのコードとより複雑なコードを1画面で見る必要があるが、さまざまなシンボリック構造の規則を学ばなければならない経験豊富なプログラマーにとってはるかに優れています。遠端にはAPLがありますが、これはほとんど完全に人間が読めません。
親密に関連する問題は明快さです-簡潔なコードはしばしば不明瞭であり、過度に冗長なコード(AppleScriptのように)も同様に不明瞭です。特定の言語に精通していると、その言語内の簡潔なコードがより明確になります-C ++コードに直面している生の初心者は、式のみを解析できる可能性が高く、機能的なBASICまたはPythonコードでさえ理解するには簡潔すぎますが、AppleScriptはできます一般的に、言語辞書に頼ることなく困惑します。私が意図的に難読化せずに遭遇した最も明確なものは、Inform 7です...
昔は
過去のもう1つの重要な考慮事項ですが、趣味のコーダーにとってはもはや重要ではないものは、操作とストレージのスペースです。(ハイエンドでは依然として重要です。)多くの言語、特にBASICフレーバーが解釈され、さらに多くの言語がランタイムコンパイルされることを念頭に置いてください。
いくつかのソリューションが存在しました-BASICではトークン化は非常に一般的でした。個々の言語キーワードは、上位128または制御文字スペースのいずれかで1または2バイトの単語に削減されました。トークン化は、バイトコードのコンパイルにもつながります(InformやZ-Machineなど)。
複数のオブジェクトファイルのコンパイルとリンクも、スペースの制限を回避するために使用されました。100KiB Pascalコードセクションは、5KiBのみにコンパイルされる場合があります。複数のコンパイル済みファイルをリンクすることにより、大容量のドライブにアクセスせずに大規模なアプリケーションを構築できます(10MiBは驚くほど大きく、新しい車を高価に購入することを思い出してください)。
しかし、より簡潔な言語では、ディスクとRAMの両方の特定のチャンクにより多くのコードが取り込まれるため、一度に大きなチャンクがコンパイルされます。覚えておいてください:1970年代初期の「ミニコンピューター」には64KiBのRAMしかありませんでした(Honeywell 800には、それぞれ8Bの2048ワードの4バンクの基本インストールがありました)。APLおよび類似のシンボリック言語は、命令とオペランドごとに1Bに近づきましたが、命令とオペランドごとにはるかに大きい3B-10Bに近づきました。(特に記号は本質的にタイプボールのフォントであり、多くのカードパンチはキーに記号がなかったため、パンチカードに入力するのは悪夢でした...)
また、カードを消去できなかったことに留意してください...多くのプログラムがカードに入力されました。個別に高価ではありませんが、コードを圧縮するほどカードに必要な数が少なくなり、プログラムが大きくなるか、安価になります。これは、BASICがほとんどのフレーバーで行ごとに複数の命令を連結している理由の一部です-パンチカードを節約するために導入されました。(または、私のVax Basicプログラミングテキストも言っています。)カードリーダー用にプログラミングしたことはありませんが、Fortran、BASIC、APL、および他のいくつかの非常に象徴的な言語でHoneywell 800のカードパンチを行いました。
非常に多くのことと同様に、答えは「冗長性」の具体的な定義に依存します。定義が冗長性を意味するようなものである場合、私はそれが常に悪いと主張します。このような定義でしばしば引用されたJavaのhello worldプログラムがなることに注意してくださいではない冗長であることで何もないので、「冗長」としての資格。
プログラマーは、表現力のある言語を好む傾向があります。これは、頻繁に行う必要のある単純なことを小さなコードでコーディングできるためです。冗長言語は、同じことを何度も繰り返すために、多くの多くのコード行を使用する必要があることを意味する傾向があります。ただし、表現力のある言語は、より単純な高レベルの言語ほど実行が速くない可能性があるため、表現力のある言語で支払うべきものがあります。CとC ++の対比で例を挙げることができれば。C ++は、コードライターに表現力を高めます。クラスの実世界のオブジェクトの概念をカプセル化できます。Cプログラマーも同じことを達成できますが、クラス構造の表現力を活用して支援します。そのため、多くの場合、より長く複雑な(理解する)コードを作成する必要があります。ただし、コードの実行にC ++の「遅延バインディング」(つまり、実行時リファクタリング)を使用しないため、そのコードは(コンパイラの品質などに大きく依存しますが)より高速に実行されます。Cはコンパイルされリンクされたコードを実行するだけで、C ++は(特定の状況で)実行時に実行するコードを決定する必要があります。
私は、読みやすさよりも根本的かつ理論的な問題に根ざした質問に対する答えがあり、この答えはグレゴリー・チャイティンが創立したアルゴリズム情報理論に関連していると信じています:http : //en.wikipedia.org/wiki/Algorithmic_information_theory。「文字列の情報内容は、その文字列の可能な限り短い自己完結型表現の長さに等しい」という短い言葉で述べます。これは、最短のプログラム(つまり、辞書編集の長さ)が特定の問題を厳密に解決することを意味します解決策を提供する問題の本質的な複雑さに一致するため、問題の表現に依存するのではなく、問題の性質に依存します。