宣言型プログラミングと命令型プログラミングの違いは何ですか?[閉まっている]
-
21-09-2019 - |
質問
私は、宣言型プログラミングと命令型プログラミングの定義を探して Web を検索しています。ただし、私が見つけたリソースの一部で使用されている言語は気の遠くなるようなものです。 ウィキペディア。この主題に何らかの視点をもたらす可能性がある実際の例 (おそらく C# で) を見せてもらえる人はいますか?
解決
宣言型と C# の優れた例命令型プログラミングはLINQです。
と 命令的 プログラミングでは、実行したいことを段階的にコンパイラーに伝えます。
たとえば、このコレクションから始めて、奇数を選択してみましょう。
List<int> collection = new List<int> { 1, 2, 3, 4, 5 };
命令型プログラミングでは、これを段階的に実行して、必要なものを決定します。
List<int> results = new List<int>();
foreach(var num in collection)
{
if (num % 2 != 0)
results.Add(num);
}
ここで、次のように言います。
- 結果コレクションを作成する
- コレクション内の各番号をステップ実行します。
- 数値を確認し、奇数の場合は結果に追加します
と 宣言的な 一方、プログラミングでは、必要なものを記述するコードを作成しますが、必ずしもそれを取得する方法は記述しません (必要な結果は宣言しますが、ステップごとは宣言しません)。
var results = collection.Where( num => num % 2 != 0);
ここで私たちが言っているのは、「奇妙なところはすべて提供してください」ということであり、「コレクションを徹底的に調べてください」ということではありません。この項目をチェックし、奇数であれば結果コレクションに追加してください。」
多くの場合、コードには両方のデザインが混在するため、必ずしも白か黒かが決まるわけではありません。
他のヒント
宣言型プログラミングはあなたが言うとき、のものをのあなたがしたい、とあなたが言うとき、命令型言語は、の方法のあなたが欲しいものを手に入れるます。
Pythonで簡単な例:
# Declarative
small_nums = [x for x in range(20) if x < 5]
# Imperative
small_nums = []
for i in range(20):
if i < 5:
small_nums.append(i)
私たちは、リストを構築するのいずれかの「実装の詳細」を指定していないので、最初の例は、宣言されます。
あなたがの方法の欲しいものを得ることは言っていないので、、宣言型スタイルでLINQの結果を使用して、一般的に、C#の例に結びつけるために、あなただけの、あなたが何をしたいのを言っています。あなたは、SQLについて同じことを言うことができます。
宣言型プログラミングの1つの利点は、コンパイラはあなたが手で作るかもしれないものよりもより良いコードになる可能性があります意思決定を行うことを可能にするということです。あなたが持っていた場合は、SQLの例で実行するようなクエリ
SELECT score FROM games WHERE id < 100;
SQL「コンパイラ」缶「最適化」このクエリそのid
がインデックス付きフィールドであることを知っているので、 - または多分それはそれはとにかくデータセット全体を反復処理する必要があります。その場合には、インデックスが作成されていません。それともSQLエンジンは、これが迅速な並列検索のために、すべての8つのコアを利用するのに最適な時間であることを知っています。 のあなたの、プログラマーとして、これらの条件のいずれかに関係していない、とあなたはその方法のいずれかの特殊なケースを処理するためのコードを記述する必要はありません。
宣言対命令型
A プログラミングパラダイムのコンピュータプログラミングの基本的なスタイルです。 4つの主要なパラダイムがあります。(宣言的パラダイムのサブセットであると考えられる)機能が不可欠、宣言、及びオブジェクト指向
宣言にプログラミング:計算ロジックを表すプログラミングパラダイムは、その制御フローを説明せずに(何)であります(どのようにしてください)。 宣言型ドメイン固有の言語(DSLの)のいくつかのよく知られた例は(例えばSELECTクエリ、)CSS、正規表現、およびSQLのサブセットを含みます こうしたHTML、MXML、XAML、XSLTなどの多くのマークアップ言語は...多くの場合、宣言されています。 命令のセットと希望の答えについての表明として、プログラムなどのプログラムの区別をあいまいにする宣言型プログラミング試します。
命令型プログラミングには:プログラムの状態を変更するステートメントの面で計算を記述するプログラミングパラダイムです。宣言型のプログラムは、二重コマンドや数学的なアサーションをプログラミングすると見ることができます。
関数型プログラミング:プログラミングパラダイムは、数学的関数の評価とことを回避する状態と可変データとして扱い計算することです。これは、状態の変化を強調命令型プログラミングスタイルとは対照的に、機能のアプリケーションを強調しています。 そのようなHaskellのような純粋な関数型言語では、すべての機能は、副作用なしであり、状態変化のみ状態を変換関数として表されている。
MSDN 、番号1〜10をループし、偶数を検索します。
var numbersOneThroughTen = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//With imperative programming, we'd step through this, and decide what we want:
var evenNumbers = new List<int>();
foreach (var number in numbersOneThroughTen)
{ if (number % 2 == 0)
{
evenNumbers.Add(number);
}
}
//The following code uses declarative programming to accomplish the same thing.
// Here, we're saying "Give us everything where it's odd"
var evenNumbers = numbersOneThroughTen.Select(number => number % 2 == 0);
の両方の実施例は、同じ結果を得、そして一つはどちらより良いも悪い以外です。最初の例では、より多くのコードが必要ですが、コードがテスト可能で、かつ不可欠なアプローチはあなたの実装の詳細を完全に制御できます。第2の例では、コードは、間違いなく、より読みやすいです。しかし、LINQを使用すると、舞台裏で何が起こるかを制御できません。あなたは、LINQは、要求された結果を提供することを信頼する必要があります。
私は別の例を追加しますめったにが、宣言/命令型プログラミングの議論にポップアップ表示しないこと!ユーザーインターフェイス
でC#は、あなたが様々な技術を使用してUIを構築することができます。
が不可欠最後に、あなたは非常に命令的あなたのボタンを描画するためにはDirectXやOpenGLを使用することができ、チェックボックス、等...ライン・バイ・ライン(または実際に、三角形によって三角形)。これは、ユーザーインターフェイスを描画する方法を言うためにあなた次第です。
宣言型の終わりには、WPFを持っています。あなたは、基本的には、いくつかのXMLを書く(ええ、ええ、「XAML」技術)およびフレームワークは、あなたのための作業を行います。あなたは、ユーザーインターフェイスのルックスが好きなものを言います。それはそれを行う方法を見つけ出すために、システムにアップします。
考えるとにかく、ちょうど別のもの。一つの言語は、宣言または不可欠であるという理由だけで、それは他の特定の機能を持っていないことを意味するものではありません。
また、宣言型プログラミングの利点の1つは、その目的は、通常より簡単に不可欠があなたに実行をより細かく制御を与える一方で、コードを読んでから理解されています。
それはすべての要旨ます:
宣言 - > what
あなたが行って欲しい。
命令型 - あなたはそれが行わたい> how
上記のすべての回答と他のオンライン投稿では、次のことが言及されています。
- と 宣言的な プログラミングでは、必要なものを記述するコードを作成しますが、必ずしもそれを取得する方法を記述する必要はありません
- 命令型プログラミングよりも宣言型プログラミングを優先する必要があります。
彼らが私たちに教えていないことは、 それを達成する方法. 。プログラムの一部をより宣言的にするには、他の部分も 抽象化を提供する 実装の詳細 ( 命令的 コード)。
- たとえば、LINQ はループ (for、while など) よりも宣言的です。たとえば、次のように使用できます。
list.Where()
新しいフィルタリングされたリストを取得します。これを機能させるために、Microsoft は LINQ 抽象化の背後ですべての重労働を実行しました。
実際、関数型プログラミングと関数型ライブラリがより宣言的である理由の 1 つは、関数型プログラミングと関数型ライブラリがループとリストの作成を抽象化し、すべての実装の詳細 (おそらくループを含む命令型コード) を舞台裏に隠しているためです。
どのようなプログラムでも、必ず命令型コードと宣言型コードの両方が存在します。目指すべきは、すべてのコードを非表示にすることです。 命令的 抽象化の背後にあるコードにより、プログラムの他の部分で使用できるようになります。 宣言的に.
最後に、関数型プログラミングと LINQ を使用するとプログラムをより宣言的にすることができますが、より多くの抽象化を提供することで、いつでもプログラムをさらに宣言的にすることができます。例えば:
// JavaScript example
// Least declarative
const bestProducts = [];
for(let i = 0; i < products.length; i++) {
let product = products[i];
if (product.rating >= 5 && product.price < 100) {
bestProducts.push(product);
}
}
// More declarative
const bestProducts = products.filter(function(product) {
return product.rating >= 5 && product.price < 100;
});
// Most declarative, implementation details are hidden in a function
const bestProducts = getBestProducts();
ケンブリッジのコースとその例からの説明が気に入りました。
- 宣言的 - 特定 何 すること、 どのようにではなく それをするために
- 例えば。:HTML は Web ページに何を表示するかを説明するものであり、画面上にどのように描画するかを説明するものではありません
- 命令的 - 両方を指定します 何 そして どうやって
int x;
- 何を (宣言的)x=x+1;
- どうやって
命令的なプログラミングでは、開発者がコードの実行方法を段階的に定義する必要があります。命令的な方法で道順を与えるために、「第1通りに行き、左折してメインに向かって2つのブロックを走り、右折してメープルに向かって、左の3番目の家で停止します」と言います。宣言バージョンは次のように聞こえるかもしれません:「スーの家まで車で。」誰かが何かをする方法を言います。もう1つは、何をする必要があるかを言います。
宣言型スタイルには、命令型スタイルに比べて次の 2 つの利点があります。
- 旅行者に長い指示を暗記することを強制するものではありません。
- これにより、旅行者は可能な場合にルートを最適化できます。
カルバート、C クルカルニ、D (2009)。必須のLINQ。アディソン・ウェスリー。48.
違いは主に全体的な抽象化レベルに関係します。宣言的では、ある時点で個々のステップから大きく離れてしまうため、結果を取得する方法に関してプログラムに大きな自由度が与えられます。
すべての命令は連続体のどこかに位置すると見ることができます。
抽象度:
Declarative <<=====|==================>> Imperative
宣言的な現実世界の例:
- 図書館員さん、白鯨の本を貸してください。(図書館員は、リクエストを実行するための最適な方法を自らの裁量で選択します)
現実世界の命令的な例:
- 図書館に行く
- Find Book 整理システム (カード カタログ - オールドスクール)
- カードカタログの使い方を調べる(あなたも忘れていますよね)
- 棚にどのようにラベルが付けられ、整理されているかを理解します。
- 本が棚にどのように整理されているかを考えてみましょう。
- カードカタログからの書籍の場所と、その書籍を検索するための組織システムとの相互参照。
- 本を持ってチェックアウトするシステム。
- 本をチェックしてください。
命令型プログラミングは順序や、
を指定するように、明示的に何をすべきか、そしてどのようにそれを行うには、コンピュータを語っていますC#ます:
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Hello World!");
}
宣言は、あなたがそれを行うには、本当にどのように何をすべきか、コンピュータを教えてではなく、ときです。データログ/ Prologは、この点でまず思い浮かぶの言語です。基本的にはすべてが宣言型です。あなたは本当に順序を保証することはできません。
C#は、はるかに命令型プログラミング言語ですが、特定のC#の機能は、LINQの
のように、より宣言されていますdynamic foo = from c in someCollection
let x = someValue * 2
where c.SomeProperty < x
select new {c.SomeProperty, c.OtherProperty};
同じことは命令的に書くことができます:
dynamic foo = SomeCollection.Where
(
c => c.SomeProperty < (SomeValue * 2)
)
.Select
(
c => new {c.SomeProperty, c.OtherProperty}
)
(ウィキペディアのLINQの例)
http://en.wikipedia.org/wiki/Declarative_programmingする からコンピュータサイエンスでは、宣言型プログラミングはその制御フローを説明することなく、計算のロジックを表すプログラミングパラダイムである。
それは制御フロー(ループ、if文など)の複雑さを欠いているので、
は一言で言えば宣言型言語は、
簡単です良い比較はASP.Net「コードビハインド」モデルです。あなたは、宣言「.ASPX」ファイルを、その後、必要不可欠 『ASPX.CS』コードファイルを持っています。私は頻繁に私は、スクリプトの宣言半分にすべてのIの必要性を行うことができれば、より多くの人々が行われているものに従うことができることがわかります。
から盗む フィリップ・ロバーツはこちら:
- 命令型プログラミングは、マシンに何かを行う方法を指示します (その結果、あなたが望むことが起こります)
- 宣言型プログラミングでは、何が起きたいのかをマシンに伝えます (そしてコンピューターはそれを行う方法を考え出します)。
2 つの例:
1.配列内のすべての数値を 2 倍にする
命令的に:
var numbers = [1,2,3,4,5]
var doubled = []
for(var i = 0; i < numbers.length; i++) {
var newNumber = numbers[i] * 2
doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]
宣言的に:
var numbers = [1,2,3,4,5]
var doubled = numbers.map(function(n) {
return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]
2.リスト内のすべての項目を合計する
命令的に
var numbers = [1,2,3,4,5]
var total = 0
for(var i = 0; i < numbers.length; i++) {
total += numbers[i]
}
console.log(total) //=> 15
宣言的に
var numbers = [1,2,3,4,5]
var total = numbers.reduce(function(sum, n) {
return sum + n
});
console.log(total) //=> 15
命令型の例では、新しい変数の作成、変数の変更、その新しい値の返し (つまり、何かを実行する方法) がどのように含まれるかに注目してください。一方、宣言型の例では、指定された入力で実行され、初期入力に基づいて新しい値が返されます (つまり、 、私たちが起こりたいこと)。
の命令型プログラミングのの< BR> そのようなC / C ++やJava、COBOL、FORTRAN、PerlやJavaScriptなどの規律をプログラミングする必要があり、プログラミング言語。そのような言語で書くプログラマは、データ処理やプログラミングの知識に基づいて、問題を解決するために、アクションの適切な順序を開発する必要があります。
を宣言型プログラミングのの< BR> 従来のプログラミングロジックを記述する必要はありませんコンピュータ言語。 ユーザーは、C ++やJavaなどの手続き型プログラミング言語で必要なプログラムステップではなく、入力と出力を定義することに集中します。
宣言型プログラミングの例ですCSS、HTML、XML、XSLT、REGXます。
ただ、モバイルアプリ開発の面で他の例を追加します。 iOSとAndroidのでは我々はアプリケーションのUIを定義することができるインターフェイスビルダーを持っています。
私たちはドラッグやコンポーネントをドロップする。ここで、これらのビルダーを使用して描かれたUIは、自然の中で、宣言されています。実際draeingは下フレームワーク及びシステムによって実行発生します。
しかし、我々はまた、コード内の全成分を描くことができ、それが自然の中で不可欠です。
また、角度JSのようないくつかの新しい言語は、宣言のUIを設計に焦点を当てていると、私たちは同じサポートを提供する他の言語の多くを見ることがあります。 JAVAはdoesnot JAVAのスイングやJAVA FXでなく、近い将来、ネイティブデスクトップアプリケーションを描画するための任意の良い宣言的な方法を持っているように、彼らだけかもしれません。
は、宣言的プログラムは、その一部多かれ少なかれ「ユニバーサル」が不可欠実装/ VMのデータだけです。
プラス: データだけを指定して、いくつかのハードコード(および確認)の形式で、簡単かつ直接的に、いくつかの不可欠アルゴリズムの変形を指定するよりもエラーが発生しやすい小さいです。いくつかの複雑な仕様は、単に一部だけDSLの形で、直接書き込むこと傾けます。 最高とDSLのデータ構造で使用FREQがセットとテーブルです。あなたは要素/行の間の依存関係を持っていないので。あなたは依存関係をhaventはとき、あなたは、変更とサポートのしやすさの自由を持っています。 (クラスと例モジュールの比較 - あなたが幸せとクラスとモジュールを使用すると、壊れやすい基本クラスの問題を抱えています) declarativenessとDSLのすべての商品は、そのデータ構造(テーブルとセット)の利点から、すぐに次の。 別のプラス - DSLは、多かれ少なかれ抽象(うまく設計された)である場合は、宣言型言語のVMの実装を変更することができます。例えば、並列実装を行います。またはポートが他のOSなどにすべての良いモジュラー絶縁インタフェースやプロトコルがあなたのサポートのように自由とeasynessを与えるspecifedます。
マイナス: あなたは正しいと思います。ジェネリック(およびDSLによってパラメータ)が不可欠アルゴリズム/ VM実装では、特定の1よりも遅く、および/またはメモリ空腹かもしれません。ある場合には。 その例はまれである場合 - ちょうどそれを忘れて、それが遅くなることができます。それはfrequientだ場合 - あなたは、常にそのような場合のために、あなたのDSL / VMを拡張することができます。どこか他のすべてのケースを遅く、必ず...
P.S。フレームワークは、DSLとの間に不可欠半分の方法です。そして、すべての中途半端なソリューションとして...彼らは欠乏症、ない利点を兼ね備えています。三面六臂で彼らそれほど安全ではないので、高速:)ない表情Haskellの - それはそれが何であるかをモンスターに強いシンプルMLと柔軟metaprogプロローグと...の中間です。あなたはブールのみの機能/述語でHaskellのようなPrologで見ることができます。そして、その柔軟性はHaskellの反対がいかに簡単で...
私は疑問に思います。このページの人気の答えはちょうど宣言型プログラミング・ツールとしてLINQについて話しています。
ウィキペディアによると
C#での一般的な宣言型言語は、データベースクエリ言語のものを含み (例えば、SQL、XQueryの)、正規表現、論理プログラミング、 関数型プログラミング、および構成管理システム。
だから、LINQは、機能的な構文として、間違いなく宣言型の方法であるが、属性クラスは、コンフィギュレーション・ツールとして、あまりにも宣言型です。ここではそれについての詳細を読むための出発点は良いです:クイックC#の属性プログラミングの概要の
私の理解から、両方の用語は、知識の宣言型と命令的な種類があり、哲学で根を持っています。宣言的知識は、真実の表明、数学の公理のような事実のステートメントです。それは伝えます あなたは何か。命令型、または手続き的知識は、あなたが何かに到達する方法をステップバイステップで伝えます。これは、アルゴリズムの定義は、本質的にあるものです。あなたが希望する場合は、英語とコンピュータ・プログラミング言語を比較します。宣言型の文章は何かを述べます。退屈な例が、ここではJavaでは、二つの数が互いに等しいか否かを表示する宣言的な方法は次のとおりです。
public static void main(String[] args)
{
System.out.print("4 = 4.");
}
英語での命令型の文章は、他の一方で、コマンドを与えるか、または要求のいくつかの並べ替えを行います。命令型プログラミングは、その後、ちょうどコマンドのリスト(それを行う、これを行う)です。ここで、Javaで、ユーザの入力を受け付けながら、二つの数が互いにかに等しいかどうか表示の不可欠な方法は次のとおりです。
private static Scanner input;
public static void main(String[] args)
{
input = new Scanner(System.in);
System.out.println();
System.out.print("Enter an integer value for x: ");
int x = input.nextInt();
System.out.print("Enter an integer value for y: ");
int y = input.nextInt();
System.out.println();
System.out.printf("%d == %d? %s\n", x, y, x == y);
}
本質的に、宣言的知識は、これらの要素の上に抽象化の層を形成するの特定の要素の上にスキップします。宣言型プログラミングは、同じことを行います。