Что такое lambda (функция)?

Для человека без comp-sci фона, что такое lambda в мире компьютерных наук?

Лямбда исходит из исчисления Лямбды и относится к анонимным функциям программирования.

Почему это круто? Это позволяет вам писать быстро отбрасываемые функции, не называя их. Он также обеспечивает хороший способ записи замыканий. С этой силой вы можете делать такие вещи.

питон

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

Как видно из fragmentа Python, сумматор функции принимает аргумент x и возвращает анонимную функцию или lambda, которая принимает другой аргумент y. Эта анонимная функция позволяет вам создавать функции из функций. Это простой пример, но он должен передать мощность lambda и замыкания.

Примеры на других языках

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 

Схема

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

C # 3.5 или выше

 Func> adder = (int x) => (int y) => x + y; // `int` declarations optional Func 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 addWithClosure = (x) => x + yEnclosed; Debug.Assert(addWithClosure(2) == 3); 

стриж

 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

 (\xy -> x + y) 

Java см. Эту запись

 // The following is an example of Predicate : // a functional interface that takes an argument // and returns a boolean primitive type. Predicate 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 

Лямбда – это тип функции, определенный в строке. Наряду с лямбдой вы также обычно имеете какой-то тип переменной, который может содержать ссылку на функцию, lambda или иначе.

Например, вот кусок кода C #, который не использует 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); } 

Это вызывает калькулятор, передавая не только два числа, но и какой метод вызывать внутри калькулятора для получения результатов расчета.

В C # 2.0 мы получили анонимные методы, которые сокращают код выше:

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

И затем в C # 3.0 мы получили lambdas, который делает код еще короче:

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

Это относится к lambda-исчислению , которое является формальной системой, которая имеет только lambda-выражения, которые представляют собой функцию, которая принимает функцию для своего единственного аргумента и возвращает функцию. Все функции в lambda-исчислении имеют такой тип, т. λ : λ → λ .

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

 (lambda (xy) (* xy)) 

Он может быть применен как в строке ( 50 ):

 ((lambda (xy) (* xy)) 5 10) 

Название «lambda» – это просто исторический артефакт. Все, о чем мы говорим, это выражение, значение которого является функцией.

Простой пример (использование Scala для следующей строки):

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

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

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

за исключением того, что вам не нужно беспокоиться:

  1. Объявление функции в другом месте (и ее нужно искать, когда вы снова просмотрите код).
  2. Именование чего-то, что вы используете только один раз.

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

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

вместо того, чтобы просто писать выражение там, где оно вам нужно:

 println(2 * a + b) 

Точная нотация варьируется от языка к языку; Греческий язык не всегда требуется! 😉

Лямбда-исчисление является последовательной математической теорией замещения. В школьной математике можно видеть, например, x+y=5 сопряженный с x−y=1 . Наряду с путями манипулирования отдельными уравнениями также можно объединить информацию из этих двух, при условии, что подстановки с поперечным уравнением выполняются логически. Исчисление Lambda кодирует правильный способ выполнения этих замещений.

Учитывая, что y = x−1 является действительной перестановкой второго уравнения, это: λ y = x−1 означает функцию, подставляющую символы x−1 для символа y . Теперь представьте себе применение λ y к каждому члену в первом уравнении. Если термин y то выполните замену; в противном случае ничего не делать. Если вы сделаете это на бумаге, вы увидите, как применение этого λ y сделает первое уравнение разрешимым.

Это ответ без какой-либо компьютерной науки или программирования.

Самый простой пример программирования, о котором я могу думать, – это http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works :

вот как квадратная функция может быть определена на императивном языке программирования (C):

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

Переменная x является формальным параметром, который заменяется фактическим значением, которое должно быть квадратично при вызове функции. В функциональном языке (схема) будет определена одна и та же функция:

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

Это по-разному, но по-прежнему использует формальный параметр x таким же образом.


Добавлено: http://imgur.com/a/XBHub

лямбда

Немного упрощенно: функция lambda – это функция, которая может быть передана другим функциям и доступна для доступа к логике.

В синтаксисе C # lambda часто компилируется в простые методы так же, как анонимные delegates, но его также можно разбить и прочитать его логику.

Например (в C # 3):

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

LinqToSql может читать эту функцию (x> 15) и преобразовывать ее в фактический SQL для выполнения с использованием деревьев выражений.

Вышеприведенное утверждение становится следующим:

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

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

Не все методы в C #, использующие синтаксис lambda, могут быть скомпилированы в деревья выражений (т.е. фактические lambda-функции). Например:

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

Теперь дерево выражений невозможно прочитать – SomeComplexCheck не может быть разбит. Оператор SQL будет выполняться без того, и каждая строка данных будет SomeComplexCheck через SomeComplexCheck .

Лямбда-функции не следует путать с анонимными методами. Например:

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

Это также имеет встроенную функцию, но на этот раз это всего лишь магия компилятора – компилятор C # разделит это на новый метод экземпляра с автогенерированным именем.

Анонимные методы не могут быть прочитаны, и поэтому логика не может быть переведена, как это возможно, для lambda-функций.

Мне нравится объяснение Lambdas в этой статье: Эволюция LINQ и ее влияние на дизайн C # . Это имело для меня большой смысл, поскольку он показывает реальный мир для Лямбдаса и создает его как практический пример.

Их быстрое объяснение: Lambdas – это способ обработки кода (функций) в качестве данных.

Пример lambda в Ruby выглядит следующим образом:

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

Будет генерировать следующий результат:

 Hello I am inside a proc 

@Brian Я все время использую lambdas в C #, в операциях LINQ и non-LINQ. Пример:

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

До C # я использовал анонимные функции в JavaScript для обратных вызовов для функций AJAX, прежде чем термин Ajax был даже придуман:

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

Интересная вещь с синтаксисом lambda C #, однако, заключается в том, что сами по себе их тип не может быть выведен (т. Е. Вы не можете вводить var foo = (x, y) => x * y), но в зависимости от того, какой тип они они будут скомпилированы в виде делегатов или абстрактных синтаксических деревьев, представляющих выражение (как это делают магические объекты объектов LINQ для своей «языковой интеграции»).

Lambdas в LISP также может быть передан оператору котировки, а затем пройден как список списков. Некоторые мощные macros сделаны таким образом.

Ответ на этот вопрос формально ответил, поэтому я не буду пытаться добавить к этому больше.

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

Практически говоря, для человека, который знает, что такое функция, я бы сказал им, что это функция, которая не имеет имени, обычно помещается в точку в памяти, которая может использоваться только путем ссылки на эту память (обычно с использованием переменная – если они слышали о концепции указателей на функции, я бы использовал их в качестве аналогичной концепции). Этот ответ охватывает довольно общие основы (без упоминания о закрытии и т. д.), но можно легко получить смысл.

Вы можете думать об этом как анонимную функцию – вот еще информация: Wikipedia – анонимная функция

У меня проблемы с обмоткой вокруг lambda-выражений, потому что я работаю в Visual FoxPro, у которого есть подстановка Macro и функции ExecScript {} и Evaluate (), которые, похоже, выполняют те же самые цели.

 ? Calculator(10, 23, "a + b") ? Calculator(10, 23, "a - b"); FUNCTION Calculator(a, b, op) RETURN Evaluate(op) 

Одно из преимуществ использования формальных лямбдов – это (я предполагаю) проверка времени компиляции: Fox не будет знать, если вы опечатаете текстовую строку выше, пока она не попытается ее запустить.

Это также полезно для кода, управляемого данными: вы можете хранить целые процедуры в полях memo в базе данных, а затем просто оценивать их во время выполнения. Это позволяет вам настроить часть приложения без фактического доступа к источнику. (Но это совсем другая тема).

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

Привет, Lambdas, версия 1

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

Привет, Lambdas, версия 2:

 void bar() {   auto f = []{printf("Hello, Lambdas\n"); };   f(); } 

Для человека без comp-sci фона, что такое lambda в мире компьютерных наук?

Я проиллюстрирую его интуитивно шаг за шагом в простых и читаемых кодах python.

Короче говоря, lambda – это просто анонимная и встроенная функция.

Давайте начнем с задания, чтобы понять lambdas как первокурсника с фоном базовой арифметики.

Схема присвоения – это «имя = значение», см.

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

‘x’, ‘y’ – это имена и 1, значение – значения. Попробуйте функцию в математике

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

Отчеты об ошибках,
вы не можете написать математику непосредственно в качестве кода, ‘n’ должно быть определено или присвоено значению.

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

Теперь он работает, что если вы настаиваете на объединении двух линий seperarte с одним. Наступает lambda

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

Ошибок не сообщалось.

Это взгляд на lambda , он позволяет вам писать функцию в одной строке, как и в математике, в компьютер напрямую.

Мы увидим это позже.

Давайте продолжим углубляться в «присвоение».

Как показано выше, символ равенства = работает для простых данных (1 и «значение») и простого выражения (n ** 2 + 2 * n + 1).

Попробуй это:

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

Он работает для простых операторов, в python имеется 11 типов . Простые операторы – документация Python 3.6.3

Как насчет составной инструкции,

 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 

Там появляется def enable it working

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

Tada, проанализируйте его, «m» – это имя, «n ** 2 + 2 * n + 1» – значение. : является вариантом ‘=’.
Найдите его, если только для понимания, все начинается с назначения, и все назначается.

Теперь вернемся к lambda , у нас есть функция с именем ‘m’

Пытаться:

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

Здесь есть два имени «m», функция m уже имеет имя, дублируется.

Это форматирование:

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

Это не умная страtagsя, поэтому отчеты об ошибках

Мы должны удалить один из них, установить функцию без имени.

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

Это называется «анонимная функция»

В заключение,

  1. lambda в встроенной функции, которая позволяет вам написать функцию в одной прямой, как это делается в математике
  2. lambda анонимно

Надеюсь это поможет.

Это функция, которая не имеет имени. Например, например, в c # вы можете использовать

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

для возврата чисел, превышающих 5.

 number => number > 5 

здесь находится lambda-часть. Он представляет функцию, которая принимает параметр (число) и возвращает логическое значение (число> 5). Метод GetMatchingItems использует эту лямбду для всех элементов коллекции и возвращает соответствующие элементы.

Я тоже это понял. Я попробовал это в JS с этим:

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

Он добавляет от 2 до 4, затем результат получается на 6. Однако мне иногда трудно читать 🙁

Также я сделал интересную функцию forEach:

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

Этот метод выполняет итерацию массива и выполняет действие – в случае печати на консоли. Теперь я тоже понимаю, почему labmdas являются мощными.

Например, в Javascript функции рассматриваются как один и тот же смешанный тип, как и все остальные ( int , string , float , bool ). Таким образом, вы можете создавать функции «на лету», назначать их вещам и называть их позже. Это полезно, но не то, что вы хотите использовать, или вы будете путать всех, кто должен поддерживать ваш код после вас …

Это какой-то код, с которым я играл, чтобы понять, насколько глубока эта кроличья дыра:

 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]()()(); 

В контексте CS lambda-функция представляет собой абстрактную математическую концепцию, которая решает проблему символической оценки математических выражений. В этом контексте lambda-функция совпадает с lambda-термином .

Но в языках программирования это нечто другое. Это fragment кода, который объявлен «на месте», и его можно передать как «первоclassного гражданина». Эта концепция оказалась полезной, так что она вошла в почти все популярные современные языки программирования (см. Lambda functions everwhere post).

В компьютерном программировании lambda – это fragment кода (оператор, выражение или группа из них), который принимает некоторые аргументы из внешнего источника. Это не всегда должно быть анонимной функцией – у нас есть много способов их реализации.

У нас есть четкое разделение между выражениями, утверждениями и функциями, которых нет у математиков.

Слово «функция» в программировании также отличается – у нас есть «функция – это последовательность шагов» (от латинского «выполнить»). В математике это связано с корреляцией между переменными.

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

На вопрос ответили полностью, я не хочу вдаваться в подробности. Я хочу поделиться использованием при написании численных вычислений в ржавчине.

Существует пример лямбды (анонимная функция)

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

Когда я писал модуль метода Ньютона-Рафсона, он использовался как производная первого и второго порядка. (Если вы хотите узнать, что такое метод Ньютона-Рафсона, посетите « https://en.wikipedia.org/wiki/Newton%27s_method ».

Выходной сигнал следующий

 println!("f={:.6} df={:.6}", f(10.0), df(10.0)) f=98.000000 df=20.000000 
  • Уравнение для тестирования, если точка находится внутри круга
  • Что такое самоуверенное программное обеспечение?
  • Сортировать по:
  • Сгенерировать список всех возможных перестановок строки
  • Болт-коллаж - обнаружение и обработка
  • Изучение теории сбора мусора
  • Что такое композиция, относящаяся к объектно-ориентированному дизайну?
  • Как проверить, пересекает ли сегмент линии прямоугольник?
  • Как работает переопределение переменных XOR?
  • Как вы находите точку на заданном перпендикулярном расстоянии от линии?
  • Линия пересечения двух плоскостей
  • Давайте будем гением компьютера.