Pour une personne sans expérience en comp-sci, qu'est-ce qu'une lambda dans le monde de l'informatique?
Pour une personne sans expérience en comp-sci, qu'est-ce qu'une lambda dans le monde de l'informatique?
Réponses:
Lambda vient du Lambda Calculus et fait référence à des fonctions anonymes dans la programmation.
Pourquoi est-ce cool? Il vous permet d'écrire des fonctions de suppression rapide sans les nommer. Il fournit également un bon moyen d'écrire des fermetures. Avec ce pouvoir, vous pouvez 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 dans l'extrait de code Python, l'additionneur de fonction prend un argument x et retourne une fonction anonyme, ou lambda, qui prend un autre argument y. Cette fonction anonyme vous permet de créer des fonctions à partir de fonctions. Ceci est un exemple simple, mais il devrait transmettre le pouvoir des lambdas et des fermetures.
Exemples dans d'autres langues
Perl 5
sub adder {
my ($x) = @_;
return sub {
my ($y) = @_;
$x + $y
}
}
my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";
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
Schème
(define adder
(lambda (x)
(lambda (y)
(+ x y))))
(define add5
(adder 5))
(add5 1)
6
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);
Rapide
func adder(x: Int) -> (Int) -> Int{
return { y in x + y }
}
let add5 = adder(5)
add5(1)
6
PHP
$a = 1;
$b = 2;
$lambda = fn () => $a + $b;
echo $lambda();
Haskell
(\x y -> x + y)
Java voir ce 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
Rubis
Ruby est légèrement différent en ce que vous ne pouvez pas appeler un lambda en utilisant exactement la même syntaxe que l'appel d'une fonction, mais il a toujours des lambdas.
def adder(x)
lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6
Ruby étant Ruby, il existe un raccourci pour lambdas, vous pouvez donc définir de adder
cette façon:
def adder(x)
-> y { x + y }
end
R
adder <- function(x) {
function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6
Un lambda est un type de fonction, défini en ligne. Avec un lambda, vous avez également généralement une sorte de type de variable qui peut contenir une référence à une fonction, lambda ou autre.
Par exemple, voici un morceau de 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);
}
Cela appelle Calculatrice, en passant non seulement deux nombres, mais la méthode à appeler dans Calculatrice pour obtenir les résultats du calcul.
En C # 2.0, nous avons obtenu des méthodes anonymes, ce qui raccourcit le code ci-dessus pour:
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 en C # 3.0, nous avons obtenu des lambdas qui rendent 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);
}
Op
, on peut simplement utiliserFunc<int, int>
Console.WriteLine("Calculator: op " + op.Method.Name + " (" + a + ", " + b + ") = " + op(a, b));
pour le premier exemple.
Le nom "lambda" n'est qu'un artefact historique. Tout ce dont 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 foreach
méthode est une expression pour une fonction anonyme. La ligne ci-dessus est plus ou moins la même chose que d'écrire quelque chose comme ça (pas du vrai code, mais vous aurez l'idée):
void printThat(Object that) {
println(that)
}
...
args.foreach(printThat)
sauf que vous n'avez pas à vous soucier de:
Une fois que vous avez l'habitude de faire fonctionner des valeurs, avoir à s'en passer semble aussi idiot qu'être obligé de nommer chaque expression, comme:
int tempVar = 2 * a + b
...
println(tempVar)
au lieu d'écrire simplement l'expression là 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! ;-)
Il fait référence au calcul lambda , qui est un système formel qui n'a que des expressions lambda, qui représentent une fonction qui prend une fonction pour son seul argument et renvoie une fonction. Toutes les fonctions du calcul lambda sont de ce type, c'est-à-dire λ : λ → λ
.
Lisp a utilisé le concept lambda pour nommer ses littéraux de fonction anonyme. Ce 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 (évalué à 50 ):
((lambda (x y) (* x y)) 5 10)
λ : λ -> λ
est déroutante (et invalide en fait).
Le calcul lambda est une théorie mathématique cohérente de la substitution. En mathématiques à l'école, on voit par exemple x+y=5
jumeler avec x−y=1
. Outre les moyens de manipuler des équations individuelles, il est également possible de rassembler les informations de ces deux, à condition que les substitutions d'équations croisées soient effectuées de manière logique. Le calcul lambda codifie la bonne façon d'effectuer ces substitutions.
Étant donné qu'il y = x−1
s'agit d'un réarrangement valide de la deuxième équation, cela: λ 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 le faites sur papier, vous verrez comment l'application de cette λ y
règle rendra la première équation résoluble.
C'est une réponse sans aucune informatique ni programmation.
L'exemple de programmation le plus simple auquel je puisse penser 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 langage de programmation impératif (C):
int square(int x) { return x * x; }
La variable x est un paramètre formel qui est remplacé par la valeur réelle à mettre au carré lors de l'appel de la fonction. Dans un langage fonctionnel (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
Légèrement simplifiée: une fonction lambda peut être transmise à d'autres fonctions et sa logique est accessible.
En C #, la syntaxe lambda est souvent compilée en méthodes simples de la même manière que les délégués anonymes, mais elle peut également être décomposée et sa logique lue.
Par exemple (en C # 3):
LinqToSqlContext.Where(
row => row.FieldName > 15 );
LinqToSql peut lire cette fonction (x> 15) et la convertir en SQL réel pour l'exécuter à l'aide d'arbres d'expression.
La déclaration 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 ne sont vraiment que de la magie du compilateur) car ils ne peuvent pas être lus .
Toutes les méthodes en C # qui utilisent la syntaxe lambda ne peuvent pas être compilées en arborescences d'expression (c'est-à-dire les fonctions lambda réelles). Par exemple:
LinqToSqlContext.Where(
row => SomeComplexCheck( row.FieldName ) );
Maintenant, l'arborescence d'expression ne peut pas être lue - SomeComplexCheck ne peut pas être décomposé. L'instruction SQL s'exécutera sans où et toutes les lignes des données seront transmises SomeComplexCheck
.
Les fonctions lambda ne doivent pas être confondues avec des méthodes anonymes. Par exemple:
LinqToSqlContext.Where(
delegate ( DataRow row ) {
return row.FieldName > 15;
} );
Cela a également une fonction `` en ligne '', mais cette fois, c'est juste de la magie du compilateur - le compilateur C # divisera cela en une nouvelle méthode d'instance avec un nom généré automatiquement.
Les méthodes anonymes ne peuvent pas être lues et la logique ne peut donc pas être traduite comme elle le peut pour les fonctions lambda.
J'aime l'explication de Lambdas dans cet article: L'évolution de LINQ et son impact sur la conception de C # . Cela avait beaucoup de sens pour moi car cela montre un monde réel pour Lambdas et le construit comme un exemple pratique.
Leur explication rapide: les lambdas sont un moyen de traiter le code (fonctions) comme des données.
Un exemple de lambda en Ruby 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
La question reçoit une réponse formelle considérable, donc je n'essaierai pas d'en ajouter plus à ce sujet.
Dans très simple, informel termes à quelqu'un qui ne connaît que 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 entrée, fait du travail et produit une sortie, n'a pas de nom particulier , mais nous savons où il se trouve et rien que par cette connaissance, nous l'utilisons.
Pratiquement parlant, pour une personne qui sait ce qu'est une fonction, je leur dirais que c'est une fonction qui n'a pas de nom, généralement mise à 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 de 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 des fermetures, etc.) mais on peut obtenir le point facilement.
@Brian J'utilise lambdas tout le temps en C #, dans les opérateurs LINQ et non-LINQ. Exemple:
string[] GetCustomerNames(IEnumerable<Customer> customers)
{ return customers.Select(c=>c.Name);
}
Avant C #, j'utilisais des fonctions anonymes en JavaScript pour les rappels aux fonctions AJAX, avant même que le terme Ajax ne soit inventé:
getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});
La chose intéressante avec la syntaxe lambda de C #, cependant, est que leur propre type ne peut pas être déduit (c'est-à-dire que vous ne pouvez pas taper var foo = (x, y) => x * y) mais en fonction du type dont ils sont assignés à, ils seront compilés en tant que délégués ou arbres de syntaxe abstraite représentant l'expression (c'est ainsi que les mappeurs d'objets LINQ font leur magie "intégrée au langage").
Les lambdas dans LISP peuvent également être transmis à un opérateur de cotation, puis parcourus sous forme de liste de listes. Certaines macros puissantes sont réalisées de cette façon.
Vous pouvez le considérer comme une fonction anonyme - voici quelques informations supplémentaires: Wikipedia - Fonction anonyme
Juste parce que je ne peux pas voir un exemple C ++ 11 ici, je vais continuer et poster ce bel exemple d' ici . Après la recherche, c'est l'exemple le plus clair spécifique à la langue que j'ai pu trouver.
template<typename F>
void Eval( const F& f ) {
f();
}
void foo() {
Eval( []{ printf("Hello, Lambdas\n"); } );
}
void bar() {
auto f = []{ printf("Hello, Lambdas\n"); };
f();
}
J'ai du mal à comprendre les expressions lambda parce que je travaille dans Visual FoxPro, qui a la substitution de macros et les fonctions ExecScript {} et Evaluate (), qui semblent servir à peu près le même objectif.
? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");
FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)
Un avantage certain de l'utilisation de lambdas formels est (je suppose) la vérification au moment de la compilation: Fox ne saura pas si vous tapez la chaîne de texte ci-dessus jusqu'à ce qu'il essaie de l'exécuter.
Cela est également utile pour le code basé sur les données: vous pouvez stocker des routines entières dans des champs de mémo dans la base de données, puis les évaluer simplement au moment de 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 tout autre sujet.)
Pour une personne sans expérience en comp-sci, qu'est-ce qu'une lambda dans le monde de l'informatique?
Je vais l'illustrer intuitivement étape par étape dans des codes python simples et lisibles.
En bref, un lambda est juste une fonction anonyme et en ligne.
Commençons par l'affectation pour comprendre lambdas
tant qu'étudiant de première année ayant des connaissances en arithmétique de base.
Le plan d'affectation est «le nom = 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 une mathématique directement sous forme de code, 'n' doit être défini ou affecté à 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 seperarte en une seule. Il vientlambda
In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>
Aucune erreur signalée.
Ceci est un coup d'œil lambda
, il vous permet d'écrire une fonction sur une seule ligne comme vous le faites directement en mathématiques dans l'ordinateur.
Nous le verrons plus tard.
Continuons à creuser plus profondément sur «l'affectation».
Comme illustré ci-dessus, le symbole égal =
fonctionne pour le type de données simples (1 et 'valeur') et l'expression simple (n ** 2 + 2 * n + 1).
Essaye ça:
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 les instructions simples, il y en a 11 types en python 7. Instructions simples - documentation Python 3.6.3
Que diriez-vous de la 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 le def
faire fonctionner
In [23]: def m(n):
...: if n > 0:
...: return n**2 + 2*n + 1
...:
In [24]: m(2)
Out[24]: 9
Tada, analyse-le, «m» est le nom, «n ** 2 + 2 * n + 1» est la valeur. :
est une variante de '='.
Trouvez-le, ne serait-ce que pour comprendre, tout commence par l'affectation et tout est affectation.
Revenons maintenant à lambda
, nous avons une fonction nommée 'm'
Essayer:
In [28]: m = m(3)
In [29]: m
Out[29]: 16
Il y a deux noms de «m» ici, la fonction a m
déjà un nom, dupliqué.
C'est un 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 ce qu'on appelle la «fonction anonyme»
En conclusion,
lambda
dans une fonction en ligne qui vous permet d'écrire une fonction sur une seule ligne droite comme le fait en mathématiqueslambda
est anonymeJ'espère que cela t'aides.
C'est une fonction qui n'a pas de nom. Par exemple, en c #, vous pouvez utiliser
numberCollection.GetMatchingItems<int>(number => number > 5);
pour renvoyer 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 ce lambda sur tous les éléments de la collection et renvoie les éléments correspondants.
En 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 affecter à des choses et les rappeler ultérieurement. C'est utile, mais ce n'est pas quelque chose que vous voulez utiliser de manière excessive ou vous confondrez tous ceux qui doivent maintenir votre code après vous ...
Voici un code avec lequel je jouais pour voir à quelle profondeur ce trou de lapin va:
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]()()();
Dans le contexte de CS, une fonction lambda est un concept mathématique abstrait qui aborde un problème d'évaluation symbolique des expressions mathématiques. Dans ce contexte, une fonction lambda est identique à un terme lambda .
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 peut être transmis en tant que «citoyen de première classe». Ce concept a semblé être utile de sorte qu'il est entré dans presque tous les langages de programmation modernes populaires (voir les fonctions lambda partout ailleurs ).
A
Lambda Function
, ou aSmall Anonymous Function
, est un bloc de fonctionnalités autonome qui peut être transmis et utilisé dans votre code. Lambda a des noms différents dans différents langages de programmation -Lambda
en Python et Kotlin ,Closure
en Swift , ouBlock
en C et Objective-C . Bien que la signification de lambda soit assez similaire pour ces langues, elle présente parfois de légères distinctions.
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]
func backward(_ n1: String, _ n2: String) -> Bool {
return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
return n1 > n2
})
reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )
reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )
reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )
reverseOrder = coffee.sorted(by: { $0 > $1 } )
// $0 and $1 are closure’s first and second String arguments.
reverseOrder = coffee.sorted(by: >)
// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]
J'espère que cela t'aides.
Je l'ai aussi. Je l'ai essayé en JS avec celui-ci:
var addAndMult = function(x) {
return (function(y) {
return (function(z) {
return (x+y)*z;
});
});
};
Il ajoute 2 à 4 puis modifie le résultat par 6. Cependant, j'ai parfois du mal à lire :(
J'ai également créé une fonction forEach intéressante:
var forEach = function(arr) {
return (function(x) {
for (var i=0; arr[i]; i++) {
x(arr[i]);
}
});
}
forEach ([1,2,3,4,5]) (console.log);
Cette méthode itérera un tableau et effectuera une action - dans le cas, l'impression sur la console. Maintenant, je comprends aussi pourquoi les labmdas sont puissants.
En programmation informatique, lambda est un morceau de code (instruction, expression ou un groupe d'entre eux) qui prend certains arguments d'une source externe. Ce 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 déclarations et les fonctions, ce que les mathématiciens n'ont pas.
Le mot "fonction" dans la programmation est également différent - nous avons "la fonction est une série d'étapes à faire" (du latin "effectuer"). En mathématiques, il s'agit de corrélation entre les variables.
Les langages fonctionnels 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 l'avons différent.
La question a été répondue pleinement, je ne veux pas entrer dans les détails. Je veux partager l'utilisation lors de l'écriture de calculs numériques en rouille.
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 };
Lorsque j'écrivais un module de la méthode de Newton – Raphson, il était utilisé comme dérivée de premier et de second ordre. (Si vous voulez savoir ce qu'est la méthode Newton – Raphson, veuillez visiter " https://en.wikipedia.org/wiki/Newton%27s_method ".
La sortie comme suit
println!("f={:.6} df={:.6}", f(10.0), df(10.0))
f=98.000000 df=20.000000
Imaginez que vous ayez un restaurant avec une option de livraison et que vous ayez une commande qui doit être effectuée en moins de 30 minutes. Le fait est que les clients ne se soucient généralement pas si vous envoyez leur nourriture à vélo avec une voiture ou pieds nus tant que vous gardez le repas au 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 nous livrons aka nous définissons un nom pour une fonction:
// ES5
var food = function withBike(kebap, coke) {
return (kebap + coke);
};
Et si nous utilisions les fonctions flèche / 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. Envoyez-le.
Btw, je ne recommande pas le kebap avec du coke, c'est pourquoi les codes supérieurs vous donneront des erreurs. S'amuser.