6

私はプログラミングにかなり慣れていないため、このラムダの概念を何度も読んでいるうちに、ラムダが実際に何であるか、それを実装することでプログラミングの生活がどのように改善されるかを理解するのに苦労しています。まず、ラムダとは何か、次にどのように実装されるのでしょうか?

投稿してくれたすべての人に感謝します。コメントで述べたように、これは重複していますが、ここには素晴らしい回答がたくさんあります。コミュニティ用に保存したいので、コミュニティの投稿に変えています。他の質問へのリンクは次のとおりです。

ラムダ (関数) とは何ですか?

4

6 に答える 6

12

ラムダは捕まえるのが難しいですが、一度イメージすると、なぜ今まで捕まえられなかったのか理解できません。

ラムバは匿名関数です

Lambda は普通の関数です。唯一の違いは、名前を付けないことです。

これを理解するには、関数を作成すると、コードがメモリ内のコンピューターだけが認識できるアドレスに格納されることを最初に理解しておく必要があります。

だからあなたがそのようなことをするとき:

function Foo ()
{
 /* your code here */
}

実際に行っているのは、「Foo」という名前をメモリ内のコードのアドレスにバインドすることです。

さて、アドレスにアクセスする別の方法があります:参照(およびポインターですが、この厄介な人はスキップしましょう)

まあ、ラムダ関数は名前のない関数なので、その参照でしかアクセスできません。

それらをどのように使用しますか?

ラムダ関数を作成するときは、通常、一度だけ使用する予定です。

通常、段階的なプロセスは次のとおりです。

  1. 関数を作成する
  2. 参照を取得する
  3. 使用される場所に参照を渡します

最後に、参照が失われるため、関数は自動的に破棄されます。

典型的な使用例は、コールバック関数です。関数の宣言、作成、受け渡しが一行で済むので便利です。

実際の言葉からの例

Python では、リスト内包表記でラムダを使用できます。

/* create a list of functions */
function_list = [(lambda x : number_to_add + x) for number_to_add in range(0, 10) ]

Javascript では、通常、関数を他の関数に渡します。JQuery の例:

 $("img").each(

 /* here we pass a function without any name to the "each()" method   */

 function(i){  his.src = "test"   i   ".jpg"; }

 );

知っておいたほうがいいこと

  • Javascript や Lisp などの一部の言語では、ラムダを大量に使用します。文化的な理由かもしれませんが、関数型プログラミングのパラダイムはラムダマニアにつながる傾向があります。

  • 長いラムダはコードを読みにくくします。そのため、「if」ステートメントを許可しない Python など、ラムダの可能性を制限する言語もあります。

  • ラムダは単なる通常の関数です。どこで使用しても、代わりに通常の関数を使用できます。それはコーディングスタイルの問題です。

于 2008-12-17T09:27:47.903 に答える
9

ラムダは、関数のインライン記述です。それは関数型プログラミング言語に端を発しており、最近では同様のものをサポートする他の言語の数が増えています。名前は関数型プログラミング言語 (Lisp など) に影響を与えたラムダ計算と呼ばれる数学的なものに由来し、ラムダのアイデアはそこから来ています。

あなたの質問は、あなたが話しているプログラミング言語によって異なります。たとえば、F# では、次fun x -> x * xを表すために使用します。

int myfunction(int x) { return x * x; }

C# ではx => x * x、同じ関数を表すために使用します。それがどのように使用され、それで何ができるかは、使用している言語によってほとんど異なります。

C# について言えば、C# の優れた点は、それらを式ツリーとして解析できることです。ラムダ式は、デリゲート(大まかに関数ポインター) のようなコードとして、または式ツリー内のデータとして使用できます。それらを式ツリーとして使用し、LINQ to SQL などのライブラリを作成して、式を使用して SQL ステートメントを作成し、サーバーに送信して適切な結果を取得できるようにします。

于 2008-12-17T06:54:39.147 に答える
6

Lambda は、匿名関数またはクロージャーを作成する手段です。命令型言語 (および関数型言語) では、内部関数が外側の関数のローカル変数とパラメーターにアクセスできるネストされた関数を許可するのと同じです。関数型言語では、キーワードlambdafunfnさらには\;の下にあります。Smalltalk ではブロックと呼ばれます。また、Perl、Python、Lua などのほとんどのスクリプト言語にも見られます。

ラムダを持たない唯一の言語について

  • 標準 C や Icon など、関数がネストされていない言語

  • 第 2 級のネストされた関数を持つ言語 --- 関数は、関数から返されたり、グローバル変数に格納されたり、ヒープ割り当てデータ構造に格納されたりすることはできません。この言語ファミリには、Pascal とその子孫である Modula、Ada、および CLU ファミリが含まれます。

ラムダは、プログラマーとコンパイラーの作成者にとって重要な意味を持ちます。スタックにすべてのローカル変数を格納することはもはや不可能です。代わりに、一部の変数がキャプチャされ、ヒープ割り当てクロージャーに格納される場合があります。ラムダを書くときは、割り当てを書いていることに注意してください。

例: 最も単純な関数の 1 つは合成 (Haskell 構文) です。

compose f g = \x -> f (g x)

これは、が引数としてとのcompose2 つの関数を取り、その引数を取り、次に に適用する無名関数を返すことを示しています。のアプリケーションは、ヒープに割り当てられたクロージャを作成します。このクロージャは、ラムダの本体のコードへのポインタだけでなく、値も格納します。Haskell、ML、Caml、Scheme など、ラムダが一般的な言語では、割り当てを盲目的に高速化するために多大な労力が費やされてきました。fgxgfxcomposefg. Lua などの一部のスクリプト言語には、非ラムダのケースを命令型言語と同じにする特殊な実装があり、ラムダをかなり高速にします。Lambda は、ヒープ上に多くのオブジェクトを割り当てるように設計された Smalltalk でも高速です。Perl や Java (内部クラスはラムダに関連しています) のように、ラムダが改良された言語では、コストが比較的高くなる可能性があります。

一般に、言語がラムダを念頭に置いて設計されている場合は、ラムダを好きなだけ使用できます。特に ML、Caml、Scheme、Haskell では、無名関数でさえ非常に安価です。それらをたくさん使用してください。

于 2008-12-17T07:53:47.937 に答える
5

プログラミングの世界でラムダとは、他のすべての通常の変数と同じように受け渡しできる無名関数を意味します。いわゆる関数型言語にはそれらが組み込まれていますが、再利用可能なコードを記述できるため、最近ではそれらをサポートする言語のセットが増えています。次のバージョンの C++ で記述された例を次に示します。

// write this once...
int transform_values(int * values, int n, function<int(int)> f) {
    for(int i = 0; i < n; i++)
        values[i] = f(values[i]);
}

int values[] = { 1, 2, 3, 4 };
// ... then call it to double the values in an array
transform_values(values, 4, [](int v) { return v * 2; });

C# やラムダをサポートする他の言語でも同様に見えます。今は「閉鎖」という言葉があります。これは、ラムダがローカル変数をキャプチャして、結果の計算に使用できることを意味します。

int local_variable = 5;
int values[] = { 1, 2, 3, 4 };
// ... then call it to multiply the values in an array
transform_values(values, 4, [=](int v) { return v * local_variable; });

変数local_variableはクロージャ内でキャプチャされ、クロージャ内で使用できるようになりました。変数は、クロージャによって更新されることもあります。ラムダは、関数型言語の基本的な構成要素です。Haskell での例を次に示します。

map (\x -> x * 2) [1, 2, 3, 4]

上記の C++ コードと同じことを行います。指定された関数 (ここではラムダ) を使用して、リスト内の値を結果リストにマップします。haskell を使用すると、使用されている構文がラムダ計算の数学的概念にどのように対応しているかをよく確認できます。

于 2008-12-17T06:58:11.527 に答える
2

Lambda はlambda calculusですが、クロージャーという用語と同じ意味で使用されていると思います。クロージャとは?を参照してください。

Ruby の実装は理解しやすく、非常に強力です。次のコードtimesでは、メソッドは中括弧の間のコード ブロックを受け取り、HEIGHT何度も呼び出します。コードのブロックを受け入れる同様のメソッドを定義し、ループ構造のようなものを実装できます。

@cells = []
HEIGHT.times { @cells << empty_row }

パラメータがあればもっと面白いと思います。

5.times { |i| puts i, " " }
于 2008-12-17T06:53:53.220 に答える
2

ラムダは、言語によって意味が異なります。Python のコンテキストではそれらについて知っていますが、Python は他の言語とは異なるアプローチを取っていると聞いたことがあります。

基本的に、Python では、ラムダは単一の式のみで構成される無名関数であり、その結果が返されます。

他の言語では、単一の式の制限がない、より一般化された無名関数であることは理解していますが、詳細についてはわかりません。

匿名関数は、まさにそのように聞こえます。名前のない関数。たとえば、これらはイベント ハンドラーとして頻繁に使用されます。または、単純なコールバック関数が必要であるが名前空間を乱雑にしたくない場合などによく使用されます。

于 2008-12-17T06:53:53.253 に答える