Вопрос

Что такое лямбда в мире компьютерных наук для человека без опыта работы в области компьютерных наук?

Это было полезно?

Решение

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

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

Питон

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

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

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

Перл 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

Схема

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

С# 3.5 или выше

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

Быстрый

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

Хаскелл

(\x y -> x + y) 

Джава видеть эта почта

// 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

Луа

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

Котлин

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true

Рубин

Ruby немного отличается тем, что вы не можете вызвать лямбду, используя тот же синтаксис, что и вызов функции, но у него все еще есть лямбды.

def adder(x)
  lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6

Ruby есть Ruby, есть сокращение для лямбда-выражений, поэтому вы можете определить adder Сюда:

def adder(x)
  -> y { x + y }
end

Другие советы

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

Например, вот фрагмент кода C#, который не использует лямбду:

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 появились лямбды, что сделало код еще короче:

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

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

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

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

Его можно применять в режиме онлайн следующим образом (оценивается как 50):

((lambda (x y) (* x y)) 5 10)

Название «лямбда» — всего лишь исторический артефакт.Все, о чем мы говорим, — это выражение, значение которого является функцией.

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

При условии 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) 
    (* x x)))

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


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

lambda

Немного упрощенно:лямбда-функция — это функция, которую можно передавать другим функциям и получать доступ к ее логике.

В 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#, использующие лямбда-синтаксис, можно скомпилировать в деревья выражений (т.настоящие лямбда-функции).Например:

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

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

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

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

Здесь также есть «встроенная» функция, но на этот раз это просто магия компилятора — компилятор C# разделит ее на новый метод экземпляра с автоматически сгенерированным именем.

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

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

Их краткое объяснение:Лямбды — это способ рассматривать код (функции) как данные.

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

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

hello.call

Сгенерирует следующий вывод:

Hello
I am inside a proc

@Brian Я постоянно использую лямбды в C#, в операторах LINQ и не-LINQ.Пример:

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

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

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

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

Лямбды в LISP также можно передавать оператору кавычек, а затем просматривать их как список списков.Некоторые мощные макросы созданы таким образом.

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

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

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

Вы можете думать об этом как об анонимной функции — вот дополнительная информация: Википедия — анонимная функция

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

Привет, Лямбдас, версия 1

template<typename F>

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

Привет, Лямбдас, версия 2:

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

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

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

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

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

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

Что такое лямбда в мире компьютерных наук для человека без опыта работы в области компьютерных наук?

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

Короче говоря, лямбда — это просто анонимная встроенная функция.

Начнем с задания, чтобы понять 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

Теперь это работает, а что, если вы настаиваете на объединении двух отдельных строк в одну?Наступает lambda

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

Об ошибках не сообщается.

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

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

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

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

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

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

Это работает для простых операторов, в Python их 11 типов. 7.Простые операторы — документация 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 включить это работать

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

Тада, проанализируй, «m» — это имя, «n**2 + 2*n + 1» — это значение.: является вариантом '='.
Найдите, хотя бы для понимания, все начинается с назначения и все есть назначение.

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

Пытаться:

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

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

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

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

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

Приходится удалить один из них, задать функцию без имени.

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

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

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

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

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

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

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

для возврата чисел, больших 5.

number => number > 5

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

Например, в 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 лямбда-функция — это абстрактное математическое понятие, которое решает проблему символьной оценки математических выражений.В этом контексте лямбда-функция аналогична лямбда-терм.

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

Я тоже это понял.Я попробовал это в 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 сильны.

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

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

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

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

А Lambda Function, или Small Anonymous Function, — это автономный функциональный блок, который можно передавать и использовать в коде.Lambda имеет разные имена в разных языках программирования – Lambda в Питон и Котлин, Closure в Быстрый, или Block в С и Цель-C.Хотя значение лямбды для этих языков очень похоже, иногда оно имеет небольшие различия.

Давайте посмотрим, как работает Lambda (Closure) в Swift 4.2 с помощью метода sorted() — от обычной функции до самого короткого выражения:

let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]

1.Нормальная функция

func backward(_ n1: String, _ n2: String) -> Bool {
    return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)


// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

2.Замыкающее выражение

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
    return n1 > n2
})

3.Встроенное замыкающее выражение

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )

4.Определение типа из контекста

reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )

5.Неявные возвраты из замыканий с одним выражением

reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )

6.Сокращенные имена аргументов

reverseOrder = coffee.sorted(by: { $0 > $1 } )

// $0 and $1 are closure’s first and second String arguments.

7.Операторные методы

reverseOrder = coffee.sorted(by: >)

// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

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

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

Вот пример лямбды (анонимной функции)

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

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

Ниже мы определили способ доставки, то есть определяем имя функции:

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

Что, если бы мы использовали стрелочные/лямбда-функции для выполнения этой передачи:

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

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

Кстати, я не рекомендую кебап с колой, поэтому верхние коды выдают ошибки.Веселиться.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top