メソッドvs機能vs手順


107

簡単な質問ですが、このような猛烈さで定義されたこれらの3つの用語をよく耳にしますが、これは長年にわたって異なることを意味することが知られています。

「手順」、「方法」、「関数」、「サブルーチン」などの「正しい」定義とは何ですか?


4
「ルーチン」を
忘れる-mefisto

1
@teresko:「サブルーチン」の方が一般的だと思います。
mk12

回答:


108

私はここで別の答えに行きます:実際には、「メソッド」は通常、オブジェクト指向言語のオブジェクトに関連付けられたサブルーチンを指すというわずかな例外を除いて、実際には違いはありません

「プロシージャ、関数、サブルーチン、サブプログラム、およびメソッド」という用語はすべて、実際には同じことを意味します。つまり、より大きいプログラム内の呼び出し可能なサブプログラムです。しかし、これらの用語はプログラミング言語やパラダイム全体で一貫して使用されていないため、これらの用語のすべてのバリエーションの使用をキャプチャする定義を見つけるのは困難です。

関数が値を返すと言うかもしれません。さて、次のC関数は値を返しません。

void f() { return; }

...しかし、それをプロシージャと呼ぶ人を見つけることはできないと思います。

確かに、Pascalでは、プロシージャは値を返さず、関数は値を返しますが、それは単にPascalの設計方法を反映したものです。Fortranでは、関数は値を返し、サブルーチンは複数の値を返します。しかし、これらの用語のいずれも、これらの用語の「普遍的な」定義を実際に思いつくことはできません。

実際、「手続き型プログラミング」という用語は、C、Fortran、およびPascalを含む言語のクラス全体を指し、そのうちの1つだけが「手続き」という用語を実際に使用して何かを意味します。

したがって、これらのどれも実際には一貫していません。おそらく唯一の例外は「メソッド」です。これは、オブジェクトに関連付けられている関数を指す、OO言語でほぼ完全に使用されているようです。ただし、これでも常に一貫しているとは限りません。たとえば、C ++は通常、メソッドではなく「メンバー関数」という用語を使用します(「メソッド」という用語は、プログラマーの間でC ++固有語に浸透しましたが)。

ポイントは、これのどれも本当に一貫性がないということです。それは、当時流行しているどの言語でも採用されている用語を単に反映しているだけです。


それがまさに答えだと思ったものです。(「サブルーチン」を後知恵で別のバリアントとして追加する必要がありました。)私は尋ねることができます:そのC関数を「プロシージャ」と呼ぶ人を見つけられないのはなぜですか?技術的に間違っているため、または「手順」という用語が現在流行していないためですか?
ジャンゴラインハルト

7
Cプログラマーが「関数」という用語を使用するのは、Cのデザイナーがその用語を使用したからです。
チャールズサルビア

15
お風呂で赤ちゃんを捨てないようにしましょう。用語が完全に一貫して使用されていないからといって、異なる用語が異なる意味を持たないという意味ではありません。@Bruceと@Frankの定義は広く認識されており、特異ではありません。意味が普遍的ではないという事実は重要ですが、それは「実際に言えば、実際に違いはありません」への飛躍を正当化するものではありません。(@Django)
LarsH

9
メソッドを「メンバー関数」、JavaおよびC#が関数「静的メソッド」を呼び出すC ++の一種。
ヨルグWミットタグ

2
ブルースの答えは間違いなく、あなたがプログラミングに慣れていない場合に行くべきものです。彼の定義は99%の確率で完全に正しいでしょう。しかし、私はもっと技術的/理論的な答えを探していました。時々、新しいプログラマーは自分のドメインだけを知っていて、それがすべてであると主張します。現実には、現在も古い言語を使用し、異なる定義を使用するために「間違っていない」プログラマーが今日働いています。それは私が最も興味だったものだった。
ジャンゴ・ラインハルト

67

関数は値を返しますが、手続きはしません。

この方法は、関数に似ているが、内部クラスの一部。メソッドという用語は、ほとんどオブジェクト指向プログラミングでのみ使用されます。


8
正確に内部ではありません。メソッドは、クラスの一部である関数またはプロシージャです。
スコットホイットロック

8
SQLの「ストアドプロシージャ」は値を返しませんか?パスカルのようなものの「手順」はどうですか?あなたの定義は現在の傾向に基づいていますか、それとも普遍的な定義とみなすべきですか?ありがとう!
ジャンゴラインハルト

3
@Django:Pascalでは、プロシージャ戻り値を持つことができず、関数戻り値を持つ必要があります。他のいくつかの言語では、用語はより緩やかに使用される場合があります。
ブルースアルダーマン

1
FWIW、FORTRANには初期の頃からSUBROUTINEとFUNCTIONがありましたが、違いはSUBROUTINEが値を返さなかったことです。Pascalの由来であるALGOLについては覚えていません。
デビッドソーン

2
@ 3p1c_d3m0n functionJSの両方の役割を果たしていることは確かですが、JS関数はすべて戻ります。returnステートメントに値がない場合、値は暗黙的になりundefinedます。returnステートメントが存在しない場合、インタープリターは暗黙的なreturnステートメントを追加します。難解かもしれませんが、ここで示した定義と一致しています。これがvar x = function() {}();、JSで合法である理由です。暗黙の戻り値でない場合、Pascalの場合と同様に、これはエラーになる必要があります。
セミコロン

52

この関数は、入力の束を取り、1つ以上の値を返すものです。戻り値が入力によって完全に決定され、関数に副作用(おそらく、ロギング、またはそれ自体の外部での状態変化の原因)がない場合、それは純粋関数と呼ばれます。

手順は、値を返さない関数です。特に、これはプロシージャが副作用のみを引き起こす可能性があることを意味します。(これには、入力パラメーターの変更が含まれる場合があります!)

この方法は、ある変数のセット、の上にクローズ機能ですクロージャ。0個以上の入力パラメーターを受け取り、この変数セットにアクセスして、0個以上の値を返します。オブジェクト指向言語では、これらのメソッドはオブジェクトまたはクラスに添付されます。

ほとんどの主流のOO言語では、これらのクローズオーバー変数は、オブジェクトのメンバーフィールドまたはインスタンス変数と呼ばれます。メソッドは、純粋関数、不純関数、またはプロシージャです。

後者の定義は、object = struct + Closures対応につながります


5
したがって、オブジェクトは変数のコレクションであり、これらの共通変数に対するクロージャーのコレクションです。基本的に、オブジェクト指向言語には常にクロージャーがあり、誰も知りませんでしたか?興味深い景色!+1
ジョルジオ

1
私はほとんどの方法が何よりも近いとは思わない。foo.doSomething()パラメータレスではありません。fooシンタックスシュガーを指定した1つのパラメーター(オブジェクト)があります。クロージャーは、そのようなパラメーターを必要とせずにオブジェクトを参照できます。それはメソッドクロージャーになれないということではなく、ほとんどがクロージャーになれないこと、そしてオブジェクト指向であることは言語がクロージャーをサポートするのに十分ではないということです。
8bittree

3
foo.doSomething()foo変数を閉じます。のステートメントは、言語に応じてまたはを介してdoSomethingアクセスできます。これはまさに「クローズオーバー」の定義です。クラスはそのメンバー変数を閉じるため、(「OOとは何か」を無視して)、OOで十分です。この文献にはかなりよく知られている...foothisself
フランクShearar

1
えー、いや foo.の前にある小さなものをご覧くださいfoo.doSomething()。それdoSomething()はパラメーターを渡すことです。括弧の間にないからといって、パラメーターではないというわけではありません。thisまたはselfメソッドの内部では、そのパラメータを参照するため、単純にシンタックスシュガーです。
8ビットツリー

1
@FrankShearar、コンピューティングには合理的に明確に区別できるのはデータと命令の2つだけだと思います。たとえそれが自己修正コードの(異常な)場合には、窓の外に出ます。オブジェクト指向では、一般に「メソッド」(または「メンバー関数」)と呼ばれるものは、定義によってメソッドまたは関数である必要はありません。その存在を暗示する「不純な機能」は、「命令」という同じ一般概念の単なる別の(そして最も長続きする、専門用語の)同義語です。
スティーブ

14

ブルースは良い答えを持っています。意味的に追加します:

  • プロシージャは、引数に対して「何かをする」か、他の副作用を引き起こす必要があります(例printf
  • 関数は、(a)引数に関する質問に答えるか、(b)引数に基づいて新しい値を計算する必要があります
  • 関数メソッドは、オブジェクトの状態に関する質問に答える必要があります
  • プロシージャメソッドは、オブジェクトの状態を変更する必要があります

素晴らしい答えです!ちょっとした追加:A procedure should "do something" to the arguments-または、他の副作用を引き起こす(例printf)。
アロングラネレク

1
@Allon printf値-印刷される文字数- を返すことに注意してください。したがって、技術的には関数です。
シェード

@Sjoerd私はそれprintfが価値であることに同意しません。呼び出し範囲外の特定の副作用がありました。つまり、標準出力が想定されているものへのI / Oです。スコットはこの区別を明示していませんでしたが、関数型プログラミングでは関数に副作用はないと想定されており、返される実際のデータがあるかのように質問に答えることができるはずです。
アラン

4

上記の良い詳細な回答; 短い話は、それらはすべてサブルーチンのフレーバーになるということです。各用語の意味は、プログラミング言語のコンテキストによって異なります

一般的に、関数は値を返しますが、する必要はありません

メソッドは現在、一般的なOOP用語です

SQLでは、ストアドプロシージャには出力がありますが、通常はエラーコードのみを返しますが、ユーザー定義関数は値(結果セットの可能性があります)を返す必要があります

繰り返しますが、これらの用語の正確な違いは、誰と話しているかによって異なります。


2

習熟度の80%は、命名法に精通していることに直接関係しています。

生産性の95%は、それを説明する用語が使用されているにもかかわらず、現時点で有用なものを特定する能力です。

私はsprocがあったMSSQLを使用したときを除いて、c#ですべてのメソッドを呼び出すことを好みますが、もちろん今ではPostgresを使用しており、関数と呼ばれています。


13
すべての統計の83.5%がその場で作成されます;-P
Django Reinhardt

1
私は、OO以外の言語で作業しているときに誰かが「メソッド」という用語を投げかけているのを聞いて緊張します。非イディオマティックなコードの実行と深く関係しているようです。
ラチェット

私が扱うOOプログラマーの多くは、手続きや機能という用語を聞くことで精神障害を抱えているため、Cコードを参照するときには「メソッド」を使用します。楽しみのために、もし私が本当にそれらをいじりたいのであれば、私はランダムに用語を交換するかもしれません。それは良くない、家にポルターガイストを招待するようなものです... :)
mattnz 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.