簡単な質問ですが、このような猛烈さで定義されたこれらの3つの用語をよく耳にしますが、これは長年にわたって異なることを意味することが知られています。
「手順」、「方法」、「関数」、「サブルーチン」などの「正しい」定義とは何ですか?
簡単な質問ですが、このような猛烈さで定義されたこれらの3つの用語をよく耳にしますが、これは長年にわたって異なることを意味することが知られています。
「手順」、「方法」、「関数」、「サブルーチン」などの「正しい」定義とは何ですか?
回答:
私はここで別の答えに行きます:実際には、「メソッド」は通常、オブジェクト指向言語のオブジェクトに関連付けられたサブルーチンを指すというわずかな例外を除いて、実際には違いはありません。
「プロシージャ、関数、サブルーチン、サブプログラム、およびメソッド」という用語はすべて、実際には同じことを意味します。つまり、より大きいプログラム内の呼び出し可能なサブプログラムです。しかし、これらの用語はプログラミング言語やパラダイム全体で一貫して使用されていないため、これらの用語のすべてのバリエーションの使用をキャプチャする定義を見つけるのは困難です。
関数が値を返すと言うかもしれません。さて、次のC関数は値を返しません。
void f() { return; }
...しかし、それをプロシージャと呼ぶ人を見つけることはできないと思います。
確かに、Pascalでは、プロシージャは値を返さず、関数は値を返しますが、それは単にPascalの設計方法を反映したものです。Fortranでは、関数は値を返し、サブルーチンは複数の値を返します。しかし、これらの用語のいずれも、これらの用語の「普遍的な」定義を実際に思いつくことはできません。
実際、「手続き型プログラミング」という用語は、C、Fortran、およびPascalを含む言語のクラス全体を指し、そのうちの1つだけが「手続き」という用語を実際に使用して何かを意味します。
したがって、これらのどれも実際には一貫していません。おそらく唯一の例外は「メソッド」です。これは、オブジェクトに関連付けられている関数を指す、OO言語でほぼ完全に使用されているようです。ただし、これでも常に一貫しているとは限りません。たとえば、C ++は通常、メソッドではなく「メンバー関数」という用語を使用します(「メソッド」という用語は、プログラマーの間でC ++固有語に浸透しましたが)。
ポイントは、これのどれも本当に一貫性がないということです。それは、当時流行しているどの言語でも採用されている用語を単に反映しているだけです。
関数は値を返しますが、手続きはしません。
この方法は、関数に似ているが、内部クラスの一部。メソッドという用語は、ほとんどオブジェクト指向プログラミングでのみ使用されます。
function
JSの両方の役割を果たしていることは確かですが、JS関数はすべて戻ります。returnステートメントに値がない場合、値は暗黙的になりundefined
ます。returnステートメントが存在しない場合、インタープリターは暗黙的なreturnステートメントを追加します。難解かもしれませんが、ここで示した定義と一致しています。これがvar x = function() {}();
、JSで合法である理由です。暗黙の戻り値でない場合、Pascalの場合と同様に、これはエラーになる必要があります。
この関数は、入力の束を取り、1つ以上の値を返すものです。戻り値が入力によって完全に決定され、関数に副作用(おそらく、ロギング、またはそれ自体の外部での状態変化の原因)がない場合、それは純粋関数と呼ばれます。
手順は、値を返さない関数です。特に、これはプロシージャが副作用のみを引き起こす可能性があることを意味します。(これには、入力パラメーターの変更が含まれる場合があります!)
この方法は、ある変数のセット、の上にクローズ機能ですクロージャ。0個以上の入力パラメーターを受け取り、この変数セットにアクセスして、0個以上の値を返します。オブジェクト指向言語では、これらのメソッドはオブジェクトまたはクラスに添付されます。
ほとんどの主流のOO言語では、これらのクローズオーバー変数は、オブジェクトのメンバーフィールドまたはインスタンス変数と呼ばれます。メソッドは、純粋関数、不純関数、またはプロシージャです。
後者の定義は、object = struct + Closures対応につながります。
foo.doSomething()
パラメータレスではありません。foo
シンタックスシュガーを指定した1つのパラメーター(オブジェクト)があります。クロージャーは、そのようなパラメーターを必要とせずにオブジェクトを参照できます。それはメソッドがクロージャーになれないということではなく、ほとんどがクロージャーになれないこと、そしてオブジェクト指向であることは言語がクロージャーをサポートするのに十分ではないということです。
foo.doSomething()
foo
変数を閉じます。のステートメントは、言語に応じてまたはを介してdoSomething
アクセスできます。これはまさに「クローズオーバー」の定義です。クラスはそのメンバー変数を閉じるため、(「OOとは何か」を無視して)、OOで十分です。この文献にはかなりよく知られている...foo
this
self
foo.
の前にある小さなものをご覧くださいfoo.doSomething()
。それdoSomething()
はパラメーターを渡すことです。括弧の間にないからといって、パラメーターではないというわけではありません。this
またはself
メソッドの内部では、そのパラメータを参照するため、単純にシンタックスシュガーです。
printf
)A procedure should "do something" to the arguments
-または、他の副作用を引き起こす(例printf
)。
printf
値-印刷される文字数- を返すことに注意してください。したがって、技術的には関数です。
printf
が価値であることに同意しません。呼び出し範囲外の特定の副作用がありました。つまり、標準出力が想定されているものへのI / Oです。スコットはこの区別を明示していませんでしたが、関数型プログラミングでは関数に副作用はないと想定されており、返される実際のデータがあるかのように質問に答えることができるはずです。
上記の良い詳細な回答; 短い話は、それらはすべてサブルーチンのフレーバーになるということです。各用語の意味は、プログラミング言語のコンテキストによって異なります
一般的に、関数は値を返しますが、する必要はありません
メソッドは現在、一般的なOOP用語です
SQLでは、ストアドプロシージャには出力がありますが、通常はエラーコードのみを返しますが、ユーザー定義関数は値(結果セットの可能性があります)を返す必要があります
繰り返しますが、これらの用語の正確な違いは、誰と話しているかによって異なります。
習熟度の80%は、命名法に精通していることに直接関係しています。
生産性の95%は、それを説明する用語が使用されているにもかかわらず、現時点で有用なものを特定する能力です。
私はsprocがあったMSSQLを使用したときを除いて、c#ですべてのメソッドを呼び出すことを好みますが、もちろん今ではPostgresを使用しており、関数と呼ばれています。