Вопрос по lambda – Что это за «лямбда», о которой все говорят?

91

Что это за «лямбда»? все продолжают говорить? Многим людям это нравится, но все, что я могу из этого извлечь, это просто способ втиснуть множество строк кода в одно выражение.

Может кто-нибудь, пожалуйста, просветите меня о его истинной ценности?

Могу ли я указать ответчикам, что спрашивающий нигде не упоминает .net anon
проверить это связанные qnstackoverflow.com/questions/16501/what-is-a-lambda-function yesraaj
Лямбды принадлежат миру функционального программирования (декларативного программирования). RBT
Главный вопрос. Спасибо за вопрос. Peanut

Ваш Ответ

14   ответов
0

Если вы знакомы с Java, вы много слышали о лямбдах или замыканиях за последние пару месяцев, потому что были разные предложения по добавлению этой функции в Java 7. Однако, я думаю, что компания отказалась от нее. Одно из предложений от Нила Гафтера и подробно объяснено здесь:javac.info, Это помогло мне понять варианты использования и преимущества (особенно перед внутренними классами)

2

Доктор Доббс Журнал имеет полезноестатья о лямбда-выражениях (в контексте C ++, но я думаю, что вы можете применить принципы к любому языку).

Как говорится в статье: «Лямбда-выражение - это очень компактное выражение, которое не требует отдельного определения класса / функции».

Итак, используя примеры списков 1 & amp; 2 изDDJ вместо того чтобы писать:

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

Что требует отдельного определения класса, такого как:

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);
}

С использованиемBoost лямбда-библиотека это может стать:

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

Который держит определение в строке.

Статья также объясняет еще несколько применений лямбда-выражений.

Я думаю, что ключевым моментом встатья DDJ is "Как правило, лямбда-выражения используются, когда на сайте вызова требуются небольшие и не слишком сложные функции. Если бы функция была нетривиальной, вы бы не хотели лямбда-выражения, но нормальной функции или функционального объекта. & Quot;

0

Для java lambdas это может быть хорошей отправной точкой:

http://rodrigouchoa.wordpress.com/2014/09/10/java-8-lambda-expressions-tutorial/

19

Термин «лямбда» используется для обозначения анонимной функции, обычнозакрытие, Они полезны, потому что они позволяют вам писать функции, которые используют другие функции, без раздувания вашего кода без необходимости. Например, в Ruby:

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

Это создаст массив, содержащий четные числа от 1 до 100. Нам не нужно выписывать явный цикл & # x2014; Метод select принимает функцию, которую он использует для проверки значений, поэтому все, что нам нужно, - это наша пользовательская логика. Это позволяет нам значительно настраивать метод практически без усилий и накладных расходов. По сути, мы можем составлять функции из меньших функций.

Это просто простой пример того, что они могут сделать. Способность передавать функции как данные является действительно мощной, а программисты на функциональных языках обычно делают с ней действительно удивительные вещи.

Это хороший ответ. Единственная причина, по которой Ионут получил мой голос, заключается в том, что он сказал нам, почему мы должны (подробно) заботиться о лямбдах.
Я бы не согласился с тем, что лямбды обычно закрыты.
Может быть, вы должны добавить, что в трубах есть параметр. Я один из тех людей, у которых проблемы с чтением рубина.
2

& APOS; лямбда & APOS; Само слово - это терминология со времен, когда типы компьютерных наук с большей вероятностью обучались математике или логике, чем ученые степени. Некоторые из них создали парадигму, называемую «функциональное программирование», весьма отличную от императивной и достаточно мощную.насколько мне известно это среда, где термин вошел в употребление.

Математикам и логикам даны странные слова.

& APOS; лямбда & APOS; звучит действительно эзотерично - как будто они очень странные и особенные вещи. Действительно, если вы пишете JavaScript для приложения веб-браузера и используете функцию & quot; var foo = function () {...} & quot; идиома, вы все время использовали лямбда-функции.

0

Для начала вы найдете все, что вам нужно знать (о C # Lambdas):
Лямбда-выражения

0

& quot; Лямбда-выражение - это анонимная функция, которая может содержать выражения и операторы и может использоваться для создания делегатов или типов дерева выражений.

Все лямбда-выражения используют лямбда-оператор = & gt ;, который читается как "идет в". Левая часть лямбда-оператора указывает входные параметры (если есть), а правая часть содержит блок выражений или операторов. Лямбда-выражение x = & gt; х * х читается "х идет к х раз х."

отMSDN

Обратите внимание, что это относится к реализации Microsoft .Net. Это не является значительным отклонением от общей идеи лямбды, но я думаю, что функциональность, реализованная в Лиспе, более "стандартна".
Да, Microsoft заставляет всех думать, что они это изобрели. Лямбда-выражения предшествуют Microsoft, хотя. Это математический термин, который был применен к нескольким языкам программирования. (Это возможно, поскольку математику можно считать компьютерным языком.)
Этот ответ совсем не объясняет, что представляет собой лямбда (требует определения анонимной функции, делегата, типа дерева выражений) и, конечно, не объясняет, каково ее значение.
2

Если вы когда-либо работали с функциями / методами, которые используют указатели функций, делегаты, стратегию или обработку шаблонов / событий наблюдателей, и подумали: «Я пишу всю эту функцию только для того, чтобы использовать ее только один раз - чтобы передать ее этой» Способ; Я хотел бы просто написать это на месте, а не загромождать свой код & quot; - здесь вы можете использовать лямбда-функции. Языки, которые поддерживают эту конструкцию, также обычно активно используют концепцию передачи функций в качестве параметров, особенно в отношении работы со списками (функции первого класса и функции более высокого порядка). Это особенно верно для функциональных языков, которые полагаются на композицию функций, а не на изменение памяти для вычислений. В некоторых случаях (в таких языках, как Python) использование лямбда-функций со списками также считается более читабельным, чем эквивалентный цикл foreach.

5

Лямбды в .NET довольно часто называют «синтаксическим сахаром». Они напрямую не влияют на функциональность, но облегчают использование языка.

Когда вы поймете всю силу их использования, я уверен, что вы обнаружите, что будете писать меньше кода по сравнению со старым стилем, используя делегаты / анонимные методы.

именно поэтому я уточнил ответом на вопрос о .net. Если другие заигрывают со своей языковой реализацией, тогда q & amp; а поможет многим людям независимо от того, какой у них язык.
Этот ответ звучит так, как будто вы что-то слышали о лямбдах, но вы сами пока их не понимаете.
Я не думаю, что кто-то упомянул .NET, поэтому, возможно, лучше использовать более общий ответ.
6

& Quot; Лямбда & Quot; может быть, слишком мало. Взгляни наЛямбда-исчисление. It's useful in functional programming.

А функциональное программирование - это еще одна парадигма программирования (как процедурная, так и объектно-ориентированная).

Рад, что вы упомянули лямбда-исчисление. +1.
Затем люди говорят о «лямбда», скорее всего, они говорят анонимную функцию, указатели на функции, замыкание или что-то подобное. Почти никогда не ссылаюсь на настоящую лямбда-исчисление.
-1

Да, это просто способ втиснуть множество строк кода в одно выражение. Но, будучи настолько эффективным, он дает некоторые новые способы структурирования вашей программы.

Часто можно было бы избежать написания делегатов или обратных вызовов и вернуться к процедурному стилю просто потому, что слишком много работы для объявления новых функций или классов для одного выражения.

Лямбда-выражения делают целесообразным использование обратных вызовов даже для крошечных задач, которые могут сделать код более понятным. Может не.

0

Для полного объяснения лямбда-выражений, также проверьтеВикипедия, (Прокрутите вниз доLambda calculus and programming languages часть.) Лямбда-выражения не так уж новы, и они не просто часть C #, а то, что было введено в вычисления почти 80 лет назад! Лямбда-выражения являются основой для функционального программирования.

Это значение? Ну, учитывая, что он на самом деле довольно старый, я бы сказал: очень ценный для тех, кто делает вычисления.

1

Лямбда-выражение - это простая форма функции. Идея состоит в том, что что-то в форме слева (эквивалент параметров) становится чем-то в форме справа (эквивалент тела).

например, в диез:

x => x * x

лямбда для возведения в квадрат значения. Нечто в форме

x

становится чем-то вроде формы

x * x
177

Functions without a name

Проще говоря, лямбда-это функция без имени или анонимная функция. Небольшой фрагмент исполняемого кода, который можно передавать как переменную. В JavaScript:

function () {}; // very simple

Теперь посмотрим, как эти лямбды используются.

Abstracting boilerplate code

Лямбды могут быть использованы для абстрагирования шаблонного кода. Например петли. Мы привыкли писатьfor а такжеwhile петли весь день Но это код, который не должен быть написан. Мы могли бы извлечь код внутри цикла, самой важной части цикла, и абстрагировать от остальных:

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

используяforEach объектов массива становится:

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

Приведенная выше абстракция может быть не такой полезной, но есть и другие функции более высокого порядка, напримерforEach, которые выполняют гораздо более полезные задачи. Например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 execution delay

В некоторых средах, в которых доступна концепция события, мы можем использовать лямбда-выражения для реагирования на события, которые могут произойти в определенный момент времени.

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

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

Это можно было бы сделать другими способами, но они довольно многословны. Например, в Java естьRunnable интерфейс.

Factories of functions

До этого момента мы использовали лямбды только для его синтаксических возможностей сахара. Но бывают ситуации, когда лямбды могут быть гораздо полезнее. Например, у нас могут быть функции, которые возвращают лямбда-выражения. Допустим, у нас есть функция, для которой мы хотим, чтобы ее возвращаемые значения кэшировались.

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];
};

Позже мы можем заметить, что у нас есть похожая функция:

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];
};

Там явно есть образец, так что давайте отвлечемся от него. Давайте использоватьмемоизации.

/**
 * @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
});

Как вы можете видеть, используя лямбды, мы смогли абстрагировать логику кэширования / запоминания. Если для другого примера были какие-то обходные пути, я считаю, что эту конкретную проблему вряд ли можно решить с помощью других методов. Нам удалось извлечь несколько важных шаблонных кодов в одном месте. Не говоря уже о том, что мы избавились отusers а такжеphotos глобальные переменные.

Просматривая ваш профиль, я вижу, что вы в основном пользователь Python. Для вышеприведенного шаблона в Python есть концепция декораторов. Есть многопример в сети для запоминания декораторы. Разница лишь в том, что в Python у вас, скорее всего, естьnamed вложенная функция внутри этой функции декоратора. Причина в том, что Python поддерживает только лямбда-выражения с одним выражением. Но концепция та же самая.

В качестве примера использования Python лямбда. Приведенный выше код, в котором мы отфильтровали четные числа, можно представить в Python следующим образом:

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

Во всяком случае, лямбды не так сильны без замыканий. Закрытия - это то, что делает концепцию лямбд столь мощной. В моем примере с памяткой я использовал замыкания для создания замыкания вокругstore пары. Таким образом, у меня есть доступ к этому параметру даже послеmemoize функция вернула свой результат (лямбда).

Вау, ты уделяешь этому много времени.
классно! действительно аккуратные вещи!
Удивительный ответ! Приятно узнавать что-то новое! :) Спасибо
Эпический ответ & lt; 15 часов & gt;
@ Mk12, в фактическом написании ответа, не совсем. При изучении этого материала, да, прошло некоторое время с тех пор, как я начал :)

Похожие вопросы