Qu'est ce qu'un lambda (fonction)?

Pour une personne sans comp-sci fond, qu'est ce qu'un lambda dans le monde de l'Informatique?

633
demandé sur nawfal 2008-08-19 20:20:37

21 réponses

Lambda vient du Lambda Calculus et se réfère à des fonctions anonymes dans la programmation.

pourquoi c'est cool? Il vous permet d'écrire rapidement jeter les fonctions sans les nommer. Il fournit également une belle façon d'écrire des fermetures. Avec ce pouvoir, tu peux faire des choses comme ça.

Python

def adder(x):
    return lambda y: x + y
add5 = adder(5)
add5(1)
6

comme vous pouvez le voir du snippet de Python, le fonction adder prend un argument x, et renvoie une fonction anonyme, ou lambda, qui prend un autre argument Y. Cette fonction anonyme vous permet de créer des fonctions à partir de fonctions. C'est un exemple simple, mais il devrait transmettre le pouvoir lambdas et les fermetures ont.

exemples dans d'autres langues

JavaScript

var adder = function (x) {
    return function (y) {
        return x + y;
    };
};
add5 = adder(5);
add5(1) == 6

JavaScript (ES6)

const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6

Régime

(define adder
    (lambda (x)
        (lambda (y)
           (+ x y))))
(define add5
    (adder 5))
(add5 1)
6

C # 3.5 ou plus

Func<int, Func<int, int>> adder = 
    (int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure = 
    (x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

Swift

func adder(x: Int) -> (Int) -> Int{
   return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = function () use (&$a, &$b) {
    echo $a + $b;
};

echo $lambda();

Haskell

(\x y -> x + y) 

Java voir this post

// The following is an example of Predicate : 
// a functional interface that takes an argument 
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
    return function(y)
        return x + y
    end
end
add5 = adder(5)
add5(1) == 6        -- true

Kotlin

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true
940
répondu mk. 2018-10-11 11:13:09

un lambda est un type de fonction, défini en ligne. Avec un lambda vous avez aussi habituellement une sorte de type variable qui peut tenir une référence à une fonction, lambda ou autre.

par exemple, voici un code C# qui n'utilise pas de lambda:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

ce calculateur appelle, en passant non seulement deux numéros, mais quelle méthode d'appeler à L'intérieur calculatrice pour obtenir les résultats du calcul.

dans C # 2.0 nous avons des méthodes anonymes, qui raccourcissent le code ci-dessus à:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

et puis dans C# 3.0 nous avons lambdas qui rend le code encore plus court:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}
96
répondu Lasse Vågsæther Karlsen 2011-11-23 01:44:01

il se réfère à calcul lambda , qui est un système formel qui vient d'avoir des expressions lambda, qui représentent une fonction qui prend une fonction pour son seul argument et retourne une fonction. Toutes les fonctions dans le calcul lambda sont de ce type, i.e., λ : λ → λ .

Lisp utilise le concept lambda pour nommer sa fonction anonyme littérales. Cette lambda représente une fonction qui prend deux arguments x et y, et retourne leur produit:

(lambda (x y) (* x y)) 

il peut être appliqué en ligne comme ceci (évalue à 50 ):

((lambda (x y) (* x y)) 5 10)
56
répondu Mark Cidade 2018-02-01 20:50:01

le nom" lambda " est juste un artefact historique. Nous parlons est une expression dont la valeur est une fonction.

un exemple simple (en utilisant Scala pour la ligne suivante) est:

args.foreach(arg => println(arg))

où l'argument de la méthode foreach est une expression pour une fonction anonyme. La ligne ci-dessus est plus ou moins la même que celle d'écrire quelque chose comme ceci (pas tout à fait du code réel, mais vous aurez l'idée):

void printThat(Object that) {
  println(that)
}
...
args.foreach(printThat)

sauf que vous n'avez pas à vous soucier de:

  1. déclarer la fonction ailleurs (et avoir à la chercher quand vous revisitez le code plus tard).
  2. nommer quelque chose que vous n'utilisez qu'une seule fois.

une fois que vous avez l'habitude de faire fonctionner les valeurs, devoir vous en passer semble aussi stupide qu'être requis pour nommer chaque expression, comme:

int tempVar = 2 * a + b
...
println(tempVar)

au lieu de il suffit d'écrire l'expression où vous en avez besoin:

println(2 * a + b)

la notation exacte varie d'une langue à l'autre; le grec n'est pas toujours requis! ;- )

50
répondu joel.neely 2008-08-29 18:36:45

le calcul lambda est une théorie mathématique cohérente de la substitution. En mathématiques scolaires, on voit par exemple x+y=5 couplé avec x−y=1 . Avec des façons de manipuler des équations individuelles, il est également possible de mettre l'information de ces deux-là ensemble, pourvu que les substitutions d'équations croisées soient faites logiquement. Lambda calculus codifie la bonne façon de faire ces substitutions.

étant donné que y = x−1 est un réarrangement valide de la deuxième équation, celle-ci: λ y = x−1 signifie une fonction remplaçant les symboles x−1 par le symbole y . Imaginez maintenant appliquer λ y à chaque terme de la première équation. Si un terme est y alors effectuer la substitution; sinon, ne rien faire. Si vous faites cela sur le papier, vous verrez comment l'application de cette λ y rendra la première équation soluble.

C'est une réponse sans aucune science informatique ou de programmation.

l'exemple de programmation le plus simple que je puisse imaginer vient de http://en.wikipedia.org/wiki/Joy_ (programming_language)#How_it_works :

voici comment la fonction carrée pourrait être définie dans un impératif langage de programmation (C):

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

, La variable x est un paramètre formel qui est remplacé par le valeur au carré lorsque la fonction est appelée. Dans une fonctionnelle langue (Scheme) la même fonction serait définie:

(define square
  (lambda (x) 
    (* x x)))

C'est différent à bien des égards, mais il utilise toujours le paramètre formel x de la même manière.


ajouté: http://imgur.com/a/XBHub

lambda

40
répondu isomorphismes 2015-09-15 04:24:35

légèrement simplifié: une fonction lambda est une fonction qui peut être passée à d'autres fonctions et c'est logique accédé.

dans la syntaxe C # lambda est souvent compilé à des méthodes simples de la même manière que les délégués anonymes, mais il peut également être décomposé et sa logique lire.

par exemple (en C#3):

LinqToSqlContext.Where( 
    row => row.FieldName > 15 );

LinqToSql peut lire cette fonction (x > 15) et la convertir en SQL pour l'exécuter en utilisant des arbres d'expression.

l'énoncé ci-dessus devient:

select ... from [tablename] 
where [FieldName] > 15      --this line was 'read' from the lambda function

c'est différent des méthodes normales ou des délégués anonymes (qui sont juste compilateur magique vraiment) parce qu'ils ne peuvent pas être lire .

toutes les méthodes en C# qui utilisent la syntaxe lambda ne peuvent pas être compilées pour exprimer les arbres (c.-à-d. les fonctions lambda réelles). Par exemple:

LinqToSqlContext.Where( 
    row => SomeComplexCheck( row.FieldName ) );

maintenant l'arbre de l'expression ne peut pas être lu - SomeComplexCheck ne peut pas être décomposé. L'instruction SQL s'exécutera sans le where, et chaque ligne des données sera passée par SomeComplexCheck .

les fonctions Lambda ne doivent pas être confondues avec les méthodes anonymes. Par exemple:

LinqToSqlContext.Where( 
    delegate ( DataRow row ) { 
        return row.FieldName > 15; 
    } );

cela a aussi une fonction 'inline', mais cette fois c'est juste de la magie de compilateur - le compilateur C# séparera cela en une nouvelle méthode d'instance avec un nom autogénéré.

les méthodes anonymes ne peuvent pas être lues, et donc la logique ne peut pas être traduite comme elle le peut pour les fonctions lambda.

13
répondu Keith 2008-08-19 17:40:58

j'ai comme l'explication des Lambdas dans cet article: L'Évolution de LINQ Et De Son Impact Sur La Conception De C# . Il a fait beaucoup de sens pour moi comme il montre un monde réel pour Lambdas et construit comme un exemple pratique.

leur explication rapide: Lambdas sont une façon de traiter le code (fonctions) comme des données.

6
répondu Jon Galloway 2008-08-19 16:29:06

un exemple de lambda en rubis est le suivant:

hello = lambda do
    puts('Hello')
    puts('I am inside a proc')
end

hello.call

générera la sortie suivante:

Hello
I am inside a proc
6
répondu CodingWithoutComments 2008-08-19 17:17:37

@Brian-je utiliser les lambdas tout le temps en C#, LINQ et non des opérateurs LINQ. Exemple:

string[] GetCustomerNames(IEnumerable<Customer> customers)
 { return customers.Select(c=>c.Name);
 }

avant C#, j'ai utilisé des fonctions anonymes en JavaScript pour les callbacks vers les fonctions AJAX, avant même que le terme Ajax soit inventé:

getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});

ce qui est intéressant avec la syntaxe lambda de C#, c'est que leur propre type ne peut pas être inféré (i.e., vous ne pouvez pas taper var foo = (x,y) => x * y) mais selon le type, ils sont assignés à, ils seront compilés sous forme de délégués ou d'arbres de syntaxe abstraite représentant l'expression (ce qui est la façon dont les cartographes D'objets LINQ font leur magie "intégrée au langage").

Lambdas dans LISP peut également être passé à un opérateur de cotation et ensuite être traversé comme une liste de listes. Quelques macros puissantes sont faites de cette façon.

4
répondu Mark Cidade 2008-08-20 09:39:22

la question est formellement répondu beaucoup, donc je ne vais pas essayer d'ajouter plus sur ce.

en très simple, informel mots à quelqu'un qui sait très peu ou rien sur les mathématiques ou la programmation, je l'expliquerais comme une petite" machine "ou" boîte " qui prend une certaine entrée, fait un certain travail et produit une certaine sortie, n'a pas de nom particulier, mais nous savons où il est et par juste cette connaissance, nous l'utilisons.

pratiquement parlant, pour une personne qui sait ce qu'est une fonction, je lui dirais que c'est une fonction qui n'a pas de nom, habituellement mis à un point dans la mémoire qui peut être utilisé simplement en se référant à cette mémoire (généralement via l'utilisation d'une variable - s'ils ont entendu parler du concept des pointeurs de fonction, je les utiliserais comme un concept similaire) - cette réponse couvre les jolies bases (aucune mention de fermetures etc) mais on peut obtenir le point facilement.

4
répondu Nick Louloudakis 2017-01-31 01:38:43

vous pouvez le considérer comme une fonction anonyme - voici plus d'informations: Wikipedia-fonction anonyme

3
répondu mercutio 2008-08-19 16:23:33

juste parce que je ne vois pas d'exemple C++11 ici, je vais aller de l'avant et poster ce bel exemple de ici . Après la recherche, c'est l'exemple le plus clair que j'ai pu trouver.

Hello, Lambdas, version 1

template<typename F>

void Eval( const F& f ) {
        f();
}
void foo() {
        Eval( []{ printf("Hello, Lambdas\n"); } );
}

Hello, Lambdas, version 2:

void bar() {
    auto f = []{ printf("Hello, Lambdas\n"); };
    f();
}
3
répondu learnvst 2018-09-30 08:23:34

j'ai du mal à enrouler ma tête autour des expressions lambda parce que je travaille dans Visual FoxPro, qui a la macro substitution et les fonctions ExecScript{} et Evaluate (), qui semblent servir à peu près le même but.

? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");

FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)

un avantage certain à utiliser lambdas formel est (je suppose) la vérification du temps de compilation: Fox ne saura pas si vous tapez la chaîne de texte ci-dessus jusqu'à ce qu'il essaie de l'exécuter.

ceci est également utile pour le code piloté par les données: vous peut stocker des routines entières dans des champs de mémo dans la base de données et ensuite les évaluer à l'exécution. Cela vous permet de modifier une partie de l'application sans avoir réellement accès à la source. (Mais c'est un autre sujet tout à fait.)

2
répondu SarekOfVulcan 2008-08-22 18:01:54

Pour une personne sans comp-sci fond, qu'est ce qu'un lambda dans le monde de l'Informatique?

Je l'illustrerai intuitivement pas à pas dans des codes python simples et lisibles.

en bref, un lambda est juste une fonction anonyme et en ligne.

commençons à partir de l'affectation pour comprendre lambdas comme une première année avec des antécédents en arithmétique de base.

le plan de l'affectation est 'le nom = la valeur', voir:

In [1]: x = 1
   ...: y = 'value'
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: 'value'

'x', 'y' sont des noms et 1, 'value' sont des valeurs. Essayez une fonction en mathématiques

In [4]: m = n**2 + 2*n + 1
NameError: name 'n' is not defined

rapports d'erreur,

vous ne pouvez pas écrire un mathematical directement comme code,'n' devrait être défini OU être assigné à une valeur.

In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396

cela fonctionne maintenant,et si vous insistez pour combiner les deux lignes de seperarte à une. Y vient lambda

In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>

aucune erreur signalée.

c'est un coup d'oeil à lambda , il vous permet d'écrire une fonction en une seule ligne comme vous le faites dans mathematic dans l'ordinateur directement.

nous le verrons plus tard.

continuons à creuser plus profondément sur "assignment".

comme illustré ci-dessus, le symbole égal = fonctionne pour des données simples(1 et 'valeur') type et expression simple (n**2 + 2*n + 1).

essayez ceci:

In [15]: x = print('This is a x')
This is a x
In [16]: x
In [17]: x = input('Enter a x: ')
Enter a x: x

cela fonctionne pour des déclarations simples,il y en a 11 types en python 7. Simple statements-Python 3.6.3 documentation

Que diriez-vous d'une déclaration composée,

In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax

Il vient def activer travail

In [23]: def m(n):
    ...:     if n > 0:
    ...:         return n**2 + 2*n + 1
    ...:
In [24]: m(2)
Out[24]: 9

Tada, analysez-le, 'm' est nom, "n**2 + 2*n + 1' est la valeur. : est une variante de '='.

Trouvez - le, si seulement pour comprendre, tout commence à partir de la tâche et tout est tâche.

maintenant retourner à lambda , nous avons une fonction appelée "m "

, Essayez:

In [28]: m = m(3)
In [29]: m
Out[29]: 16

il y a deux noms de 'm' ici, la fonction m a déjà un nom, dupliqué.

c'est du formatage comme:

In [27]: m = def m(n):
    ...:         if n > 0:
    ...:             return n**2 + 2*n + 1
    SyntaxError: invalid syntax

ce n'est pas une stratégie intelligente, donc les rapports d'erreur

nous devons supprimer l'un d'eux,définir une fonction sans nom.

m = lambda n:n**2 + 2*n + 1

C'est appelé "fonction anonyme"

en conclusion,

  1. lambda dans une fonction en ligne qui vous permettent d'écrire une fonction en ligne droite comme le fait en mathématiques
  2. lambda est anonyme

l'Espoir, cela aide.

2
répondu JawSaw 2018-01-16 17:58:47

C'est une fonction qui n'a pas de nom. Pour par exemple dans c# vous pouvez utiliser

numberCollection.GetMatchingItems<int>(number => number > 5);

pour retourner les nombres supérieurs à 5.

number => number > 5

est la partie lambda ici. Il représente une fonction qui prend un paramètre (nombre) et renvoie une valeur booléenne (nombre > 5). La méthode getmatchingitems utilise cette lambda sur tous les articles de la collection et renvoie les articles correspondants.

1
répondu Serhat Ozgel 2008-08-19 16:28:41

je l'ai eu aussi. J'ai essayé dans JS avec celui-ci:

var addAndMult = function(x) {
        return (function(y) {
            return (function(z) {
                return (x+y)*z; 
                });
            });
        };

il ajoute 2 à 4 puis mults le résultat par 6. Cependant je trouve parfois difficile de lire : (

J'ai aussi fait une intéressante fonction forEach:

var forEach = function(arr) {
            return (function(x) {
            for (var i=0; arr[i]; i++) {
                 x(arr[i]);
             }
        });
    }

forEach([1,2,3,4,5])(de la console.journal);

cette méthode itérera un tableau et effectuera une action - dans le cas de l'impression à la console. Maintenant je comprends aussi pourquoi les labmdas sont puissant.

1
répondu Ilian Zapryanov 2012-12-04 19:52:50

dans Javascript, par exemple, les fonctions sont traitées comme le même type mixte que tout le reste ( int , string , float , bool ). En tant que tel, vous pouvez créer des fonctions à la volée, les assigner à des choses, et les rappeler plus tard. C'est utile mais, pas quelque chose que vous voulez surutiliser ou vous allez confondre tous ceux qui doivent maintenir votre code après vous...

c'est un code avec lequel je jouais pour voir la profondeur de ce terrier de lapin:

var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }

for(var i=0 ;i<3; i++)
    x.thingy[i]()()();
1
répondu Michael 2016-01-28 22:03:30

Dans le contexte de CS un lambda est une fonction mathématique abstrait concept qui s'attaque à un problème de la symbolique de l'évaluation des expressions mathématiques. Dans ce contexte, une fonction lambda est la même qu'un lambda terme .

mais dans les langages de programmation c'est quelque chose de différent. C'est un morceau de code qui est déclaré "en place", et qui peuvent être passés comme un "citoyen de première classe". Ce concept est apparu utile pour qu'il soit presque tous les langages de programmation modernes populaires (voir lambda fonctions everwhere post).

1
répondu battlmonstr 2016-08-20 21:40:45

dans la programmation informatique, lambda est un morceau de code (énoncé, expression ou un groupe d'entre eux) qui prend quelques arguments d'une source externe. Il ne doit pas toujours être une fonction anonyme - nous avons plusieurs façons de les mettre en œuvre.

nous avons une séparation claire entre les expressions, les énoncés et les fonctions, que les mathématiciens n'ont pas.

le mot "fonction" dans la programmation est également différent - nous avons " fonction est une série d'étapes à faire" (du Latin "exécuter"). En mathématiques, c'est une question de corrélation entre les variables.

les langues fonctionnelles essaient d'être aussi similaires que possible aux formules mathématiques, et leurs mots signifient presque la même chose. Mais dans d'autres langages de programmation, nous avons différents.

1
répondu konmik 2017-07-09 22:16:42

la question a reçu une réponse complète, Je ne veux pas entrer dans les détails. Je veux partager l'usage en écrivant des calculs numériques dans rust.

il y a un exemple de lambda (fonction anonyme)

let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };

quand j'écrivais un module de la méthode Newton–Raphson, il a été utilisé comme dérivé de premier et deuxième ordre. (Si vous voulez savoir ce qu'est la méthode Newton–Raphson, s'il vous plaît visitez " https://en.wikipedia.org/wiki/Newton%27s_method ".

La sortie de la suite de

println!("f={:.6}      df={:.6}", f(10.0), df(10.0))

f=98.000000       df=20.000000
0
répondu madeinQuant 2018-05-22 04:18:39

Imaginez que vous ayez un restaurant avec une option de livraison et que vous ayez une commande qui doit être faite en moins de 30 minutes. Le point est que les clients ne se soucient généralement pas si vous envoyez leur nourriture à vélo avec une voiture ou pieds nus aussi longtemps que vous gardez le repas chaud et attaché. Permet donc de convertir cet idiome en Javascript avec des fonctions de transport anonymes et définies.

ci-dessous nous avons défini la façon dont notre AKA de livraison nous définissons un nom à une fonction:

// ES5 
var food = function withBike(kebap, coke) {
return (kebap + coke); 
};

et si nous utilisions les fonctions arrow/lambda pour effectuer ce transfert:

// ES6    
const food = (kebap, coke) => { return kebap + coke };

vous voyez qu'il n'y a pas de différence pour le client et pas de perte de temps pour réfléchir à la façon d'envoyer de la nourriture. Il suffit de lui envoyer.

Btw, Je ne recommande pas le kebap avec coke c'est pourquoi les codes supérieurs vous donneront des erreurs. Amuser.

0
répondu Shopska 2018-10-04 12:56:15