92 votes

Qu'est-ce que c'est 'Lambda' dont tout le monde parle?

Qu'est-ce que c'est 'Lambda' dont tout le monde parle? Cela semble plaire à beaucoup de gens, mais tout ce que je peux en déduire, c’est que c’est simplement une façon de regrouper de nombreuses lignes de code dans une seule expression.

Quelqu'un peut-il s'il vous plaît m'éclairer sur sa vraie valeur?

178voto

Ionuț G. Stan Points 62482

Fonctions sans nom

Il suffit de mettre, une lambda est une fonction sans nom, ou une fonction anonyme. Un petit morceau de code exécutable, qui peuvent être passés comme si c'était une variable. En JavaScript:

function () {}; // very simple

Nous allons voir maintenant quelques utilisations de ces lambdas.

L'abstraction de code réutilisable

Les Lambdas peuvent être utilisés de faire abstraction de code réutilisable. Par exemple des boucles. Nous avons l'habitude d'écrire for et while boucles tout au long de la journée. Mais c'est le code qui n'est pas écrit. Nous avons pu extraire le code à l'intérieur de la boucle, la partie la plus importante de la boucle, et abstraction du reste:

for (var i=0; i<array.length; i++) {
    // do what something useful with array[i]
}

en utilisant l' forEach de tableau d'objets, devient:

array.forEach(function (element, index) {
   // do something useful with element
   // element is the equivalent of array[i] from above
});

La au-dessus de l'abstraction peut ne pas être utile, mais il y a d'autres des fonctions d'ordre supérieur, comme forEach, qui effectuent beaucoup plus de tâches utiles. Par exemple filter:

var numbers = [1, 2, 3, 4];
var even    = [];

// keep all even numbers from above array
for (var i=0; i<numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
        even.push(numbers[i]);
    }
}

alert(even);

// Using the filter method
even = [1, 2, 3, 4].filter(function (number) {
    return number % 2 === 0;
});

alert(even);

Code délai d'exécution

Dans certains environnements, dans lesquels le concept de l'événement est disponible, on peut utiliser des lambdas pour répondre à des événements qui peuvent se produire à un certain point dans le temps.

window.onload = function () {
    alert("Loaded");
};

window.setTimeout(function () {
    alert("Code executed after 2 seconds.");
}, 2000);

Cela aurait pu être fait dans d'autres façons, mais ceux-ci sont assez bavard. Par exemple, en Java il y a l' Runnable interface.

Les usines de fonctions

Jusqu'à ce point, nous n'avons utilisé que les lambdas pour son sucre syntaxique des capacités pour la plupart. Mais il existe des situations où elles peuvent être beaucoup plus utile. Pour exemple, on peut avoir les fonctions qui retournent des lambdas. Disons que nous avons une fonction que nous voulons que les valeurs de retour d'être mis en cache.

var users = [];
var getUser = function (name) {
    if (! users[name]) {
        // expensive operations to get a user. Ajax for example
        users[name] = user_from_ajax;
    }

    return users[name];
};

Plus tard, nous pouvons remarquer que nous avons une fonction similaire:

var photos = [];
var getPhoto = function (name) {
    if (! photo[name]) {
        // expensive operations to get a user. Ajax for example
        photos[name] = photo_from_ajax;
    }

    return photos[name];
};

Il y a clairement un motif de là, nous allons donc abstraite. Nous allons utiliser memoization.

/**
 * @param {Array}     store Data structure in which we cache lambda's return values
 * @param {Function}  lambda
 * @return {Function} A function that caches the result of calling the lambda param
 */
var memoize = function (store, lambda) {
    // return a new lambda
    return function (name) {
        if (! store[name]) {
            // Execute the lambda and cache the result
            store[name] = lambda(name);
        }

        return store[name];
    };
};

var getUsers = memoize([], function (name) {
    // expensive operations to get a user. Ajax for example
});

var getPhotos = memoize([], function (name) {
    // expensive operations to get a photo. Ajax for example
});

Comme vous pouvez le voir, en utilisant les lambdas, nous avons été en mesure de faire abstraction de la mise en cache/memoization logique. Si pour l'autre exemple, il y avait quelques solutions de contournement, je crois que ce problème est à peine résolu en utilisant d'autres techniques. Nous avons réussi à extraire une partie importante du code réutilisable en un seul endroit. Pour ne pas mentionner que nous sommes débarrassés de l' users et photos des variables globales.

Regardant votre profil, je vois que vous êtes plutôt un Python de l'utilisateur. Pour le modèle, Python est le concept de décorateurs. Il y a beaucoup d' exemple sur le net pour memoization décorateurs. La seule différence est que dans Python-vous le plus de chances d'avoir un nommé fonction imbriquée à l'intérieur de cette fonction décorateur. La raison étant que le Python uniquement en charge une seule expression lambda. Mais le concept est le même.

Comme un exemple de Python lambda utilisation. Le code ci-dessus dans laquelle nous avons filtré les même numéros peut être représenté en Python comme ceci:

filter(lambda x: x % 2 == 0, [1, 2, 3, 4])

De toute façon, les lambdas ne sont pas puissants, sans fermetures. Fermetures est ce qui rend le concept de lambdas si puissant. Dans mon memoization exemple, j'ai utilisé des fermetures pour créer une clôture autour de l' store param. De cette façon, j'ai accès à ce param même après l' memoize fonction a retourné son résultat (lambda).

19voto

Chuck Points 138930

Le terme "lambda" est utilisé pour désigner une fonction anonyme, généralement une fermeture. Ils sont utiles car ils vous permettent d'écrire des fonctions qui utilisent d'autres fonctions sans ballonnements votre code inutilement. Par exemple, en Ruby:

(1..100).select {|num| num % 2 == 0}

Cela va créer un tableau contenant le même nombre entre 1 et 100. Nous n'avons pas à écrire explicitement la boucle de la méthode de sélection prend une fonction qu'il utilise pour tester les valeurs, de sorte que tous nous avons besoin est notre logique personnalisée. Cela nous permet de personnaliser grandement la méthode avec pratiquement aucun effort ou des frais généraux. Fondamentalement, nous pouvons composer des fonctions de petites fonctions.

C'est juste un exemple simple de ce qu'ils peuvent faire. La possibilité de passer des fonctions en tant que données est vraiment puissant et fonctionnel de la langue programmeurs font vraiment des choses étonnantes avec elle.

6voto

H_I Points 170

"Lambda" peut-être juste trop peu. Jetez un coup d'œil au calcul Lambda . C'est utile en programmation fonctionnelle.

Et la programmation fonctionnelle est encore un autre paradigme de programmation (comme procédural, ou orienté objet).

5voto

redsquare Points 47518

Les lambda dans .NET sont assez souvent appelés «sucre syntaxique». Ils n'affectent pas directement les fonctionnalités, mais ils facilitent l'utilisation du langage par les utilisateurs.

Une fois que vous aurez compris le pouvoir de les utiliser, vous constaterez que vous écrivez moins de code que l’ancien style utilisant des méthodes délégués / anonymes.

2voto

danio Points 2962

Dr Dobbs Journal a un utile article de présentation des expressions lambda (dans le contexte de C++, mais je pense que vous pouvez en appliquer les principes à n'importe quelle langue).

Comme le dit l'article: "Une expression lambda est une très compacte expression qui ne nécessitent pas une catégorie distincte/définition de la fonction."

Donc, en utilisant les exemples de listes 1 et 2 de DDJ au lieu d'écrire:

std::for_each( vec.begin(), vec.end(), print_to_stream<std::string>(std::cout));

Ce qui nécessite une catégorie distincte de définition comme:

template <typename T, typename Stream> class print_to_stream_t {
  Stream& stream_;
public:
  print_to_stream_t(Stream& s):stream_(s) {}
  void operator()(const T& t) const {
    stream_ << t;
  }
};
template <typename T,typename Stream> 
print_to_stream_t<T,Stream>   print_to_stream(Stream& s) {
  return print_to_stream_t<T,Stream>(s);
}

En utilisant le Boost lambda de la bibliothèque , cela peut devenir:

std::for_each(vec.begin(),vec.end(),std::cout << _1);

Ce qui maintient la définition de la ligne.

L'article explique également certaines applications d'expressions lambda.

Je pense que d'un point clé dans le DDJ l'article est "en général, les expressions lambda sont utilisés lorsque de petites et pas trop complexe fonctions sont nécessaires sur le site d'appel. Si la fonction a été non négligeable, vous ne voulez pas d'une expression lambda, mais une fonction normale ou une fonction de l'objet."

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X