web-dev-qa-db-ja.com

手続き型プログラミングとは正確には何ですか?それはOOPとどの程度正確に異なりますか?関数型プログラミングと同じですか?

私は非常にオブジェクト指向(OO)スタイルで Java でプログラミングしています。 OOPは非常に直感的に理解できますが、他の種類のプログラミングについてはほとんど知識がありません。

正確には 手続き型プログラミング とは何ですか?それはOOPとどの程度正確に異なりますか? 関数型プログラミング と同じですか?

OOでないプログラミングはすべて手続き型であると考えていましたが、これは真実ではないと思い始めています。

32
Aviv Cohn

ウィキペディアには、これらの用語についての適切な説明があります。とにかく、ここに要約があります:

  • 命令型プログラミング 変更可能な状態を変更する一連のステートメントとして計算をモデル化します。
  • 手続き型プログラミング は、コードをサブルーチンに分解する命令型プログラミングです。
  • 構造化プログラミング は、任意のジャンプ(例:goto)とグローバルな状態変化を禁止する手続き型プログラミングへのより統制のとれたアプローチです。

  • 宣言型プログラミング は命令型プログラミングの反対です-計算方法ではなく計算対象を指定します(SQL、正規表現など)。

  • 関数型プログラミング 計算をとしてモデル化し、値を生成する場合があります。関数は値であり、他の関数に渡したり、他の関数から返すことができます。突然変異はお勧めできません。すべての変数はデフォルトで不変です。その結果、命令を達成するために必要な一連の状態変化ではなく、計算されているものを強調するため、命令型よりも宣言型になります。

  • 純粋に関数型のプログラミング ミューテーションを完全に禁止します(ただし、一般的な考えに反して、依然として副作用を達成するためのメカニズムはあります)。
  • 合計関数型プログラミング は、例外と無限ループをさらに禁止します。 (数学の合計関数は、その入力のallの値を返す関数です。)

OOPはかなりロードされた用語であるため、それらの関係は少し複雑です。オブジェクトは関数型言語と手続き型言語の両方で使用できますが、OOとしてアドバタイズする言語は手続き型です。問題をさらに混乱させるには:

  • ほとんどの人は知らない オブジェクトと抽象データ型の違い
  • 主流のOOP言語はADTについて言及しておらず、ADTのサポートが非常に貧弱であり、オブジェクトをThe One True Wayとして宣伝しています。
  • Abstract Data Type-Oriented Programming(ばかげたことになるので、ADTとオブジェクトの両方が必要なため)

これにより、人々はOOPが抽象化を実現するための唯一の方法であると考えるようになり、関数型プログラミングとOOPは何らかの形で反対または相互に排他的です。多くの人々はまた、すべての関数型言語は純粋であり、変異を許可しないと考えています。

さらに、人々は一般に命令型/手続き型を交互に利用し、時にはOOP(抽象化のないコード、一般的にはCを意味する)とは対照的であり、関数型プログラミングとは対照的です。 構造化プログラミングという用語は、私が知る限り、ほとんど使用されなくなっています(この時点で、ほとんどの人はgotoとグローバルは有害であると考えていることを当然のことと思っているためです)。

69
Doval

手続き型プログラミングは、他の多くの言語設計(機能が1つではない)のビルディングブロックの基本の1つであるプログラミングへのアプローチです。

ほとんどの言語は「手続き型プログラミング」のセットに分類され、おそらくほとんどの人にとって最も自然な設計手法です(オブジェクト指向の観点から考えると、少数派だと思います)。

BASICは手続き型です。

他の人が言ったように、それはプログラムを順番に構成するためのメカニズムです。

  • 最初にxを行います
  • 二番目に
  • 第三に、私はZをします

「手続き」を定義するためのメカニズムが必要です。OOメソッドに類似した名前付きコードのブロックで、0から多くのパラメーターを受け入れ、オプションで値を返すことができます(これは通常、関数と呼ばれます) -おそらく関数型言語との混乱を招くでしょう)

パラダイムは、あなたが何をするか、または周りに渡されるものの方法を指示しません。

これは、プログラムが順次動作する一連のプロシージャ(または関数)として構成されることを簡単に説明しています。次に、データは手順とは無関係に定義されます。

これは、データの集合とそのデータに作用するメソッド(関数ではない)を中心にプログラムを構成するオブジェクト指向プログラミングとは異なります。

これについて考える1つの方法は、データスコープの観点からです。

手続き型言語では、スコープはかなり単純です。変数は、(ローカルで宣言された)与えられたプロシージャのスコープ内にあり、(グローバルに宣言された)呼び出し元のレベルまで、ネストされたスコープを持ちます。

オブジェクト指向言語では、新しいスコープコンテキストを追加します。これは、現在使用されているオブジェクトのスコープコンテキストであり、上記とは直交しています。

オブジェクト指向と比較して、手続き型について考えるもう1つの方法は、すべてのメソッドmustが静的として宣言されているオブジェクト指向言語を検討することです。その結果、クラスを使用してプロシージャをグループ化できる手続き型言語が得られます。

12
Rob Baillie

手続き型プログラミング は関数型プログラミングではありません。

手続き型プログラミングとは、コンピュータのモデルを頭の中に持ち、メモリ内のデータをどのように変更するかを考えている場合です。したがって、最初にAを値3に設定し、次に1を追加して、それをメモリロケーションAに再度格納します(以前の値を上書きします)。

関数型プログラミングでは、Aは3、BA + 1、次にコンピュータにBの計算方法を計算させます。 Aを定義したら、shouldは不変(変更不可)です。また、Functionalを使用すると、関数をファーストクラスの値として渡すことができます(関数は関数を引数として取ることができます)。

オブジェクト指向プログラミングは、多くの場合、両方を組み合わせており、ある程度直交しています。関数型プログラミングを使用して不変オブジェクトを返すことができます。そのオブジェクトには、計算された値を返すメソッドを含めることができ、それを遅延して実行することもできます。これは関数型オブジェクト指向プログラミングです。 「リポジトリ」(データベースの抽象的なバージョン)を表すオブジェクトを作成することもできます。また、リポジトリにデータを「保存」したり、データを「取得」したり、そのオブジェクトに処理の詳細をすべて処理させたりすることもできます。 。これは基本的にオブジェクト指向の手続き型プログラミングです。

5
Scott Whitlock

OOPは、手続き型プログラミングの少し洗練された形式にすぎません。これも、命令型プログラミングのより大きなファミリに属しています。その主張の証拠は、多くのC#/ Javaプログラマーが「何かをする」傾向があり、次のような方法を好むことです。

void doThisAndThat(....) { ... do something ... }

したがって、一連のvoidメソッド(以前はprocedures(sic!)と呼ばれていました)と次のようなコードで構成されるプログラム:

doThis();
if (state is that) doSomethingElse();
doThat();

完璧な手続き型プログラミングです。

0
Ingo