uma - what is lambda programming




O que é um lambda(função)? (15)

Para uma pessoa sem histórico de comp-sci, o que é um lambda no mundo da ciência da computação?

Ilustrarei intuitivamente passo a passo em códigos python simples e legíveis.

Em suma, um lambda é apenas uma função anônima e inline.

Vamos começar a partir da tarefa de entender lambdas como um calouro com histórico de aritmética básica.

O plano de designação é 'o nome = valor', consulte:

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

'x', 'y' são nomes e 1, 'valor' são valores. Tente uma função em matemática

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

Relatórios de erros
você não pode escrever uma matemática diretamente como código, 'n' deve ser definido ou ser atribuído a um valor.

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

Funciona agora, e se você insistir em combinar as duas linhas seperarte em uma. Lá vem lambda

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

Nenhum erro relatado.

Este é um relance no lambda , ele permite que você escreva uma função em uma única linha como você faz em matemática diretamente no computador.

Nós veremos mais tarde.

Vamos continuar cavando mais fundo em 'atribuição'.

Como ilustrado acima, o símbolo equals = trabalha para dados simples (1 e 'valor') e expressão simples (n ** 2 + 2 * n + 1).

Tente isto:

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

Ele funciona para instruções simples, há 11 tipos deles em Python 7. Instruções simples - Documentação do Python 3.6.3

Como cerca de declaração composta,

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

Lá vem def habilitar isso funcionando

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

Tada, analise, 'm' é nome, 'n ** 2 + 2 * n + 1' é o valor. : é uma variante de '='.
Encontrá-lo, se apenas por compreensão, tudo começa a partir de atribuição e tudo é atribuição.

Agora volte para lambda , temos uma função chamada 'm'

Experimentar:

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

Existem dois nomes de 'm' aqui, a função m já tem um nome duplicado.

Está formatando como:

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

Não é uma estratégia inteligente, então relatórios de erro

Temos que deletar um deles, definir uma função sem nome.

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

É chamado de 'função anônima'

Em conclusão,

  1. lambda em uma função inline que permite escrever uma função em uma linha reta como na matemática
  2. lambda é anônimo

Espero que isto ajude.

Para uma pessoa sem histórico de comp-sci, o que é um lambda no mundo da ciência da computação?


Uma Lambda Function ou uma Small Anonymous Function é um bloco autocontido de funcionalidade que pode ser passado e usado em seu código. O Lambda tem nomes diferentes em linguagens de programação diferentes - Lambda em Python e Kotlin , Closure em Swift ou Block em C e Objective-C . Embora o significado de lambda seja bastante similar para essas línguas, às vezes tem ligeiras distinções.

Vamos ver como o Lambda (Closure) funciona no Swift 4.2 com o método sorted () - da função normal até a expressão mais curta:

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

1. Função Normal

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


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

2. Expressão de Encerramento

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

3. Expressão de Encerramento Inline

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

4. Tipo de Inferimento do Contexto

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

5. Retornos Implícitos de Fechamentos de Expressão Única

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

6. Nomes de Argumentos Abreviados

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

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

7. Métodos do Operador

reverseOrder = coffee.sorted(by: >)

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

Espero que isto ajude.


@ Brian eu uso lambdas o tempo todo em C #, em operadores LINQ e não-LINQ. Exemplo:

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

Antes do C #, eu usava funções anônimas em JavaScript para retornos de chamadas para funções do AJAX, antes mesmo que o termo Ajax fosse cunhado:

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

O interessante da sintaxe lambda do C #, no entanto, é que o tipo deles não pode ser inferido (ou seja, você não pode digitar var foo = (x, y) => x * y), mas dependendo de qual tipo eles são atribuídos a eles, eles serão compilados como delegados ou árvores de sintaxe abstrata representando a expressão (que é como os mapeadores de objeto LINQ fazem sua mágica "integrada à linguagem").

Lambdas no LISP também pode ser passado para um operador de cotação e, em seguida, percorrido como uma lista de listas. Algumas macros poderosas são feitas dessa maneira.


A questão é formalmente respondida muito, então eu não vou tentar adicionar mais sobre isso.

Em palavras muito simples e informais para alguém que sabe muito pouco ou nada sobre matemática ou programação, eu explicaria isso como uma pequena "máquina" ou "caixa" que toma alguma entrada, faz algum trabalho e produz alguma saída, não tem nome específico , mas nós sabemos onde é e apenas por este conhecimento, nós o usamos.

Praticamente falando, para uma pessoa que sabe o que é uma função, eu diria a eles que é uma função que não tem nome, geralmente colocada em um ponto na memória que pode ser usado apenas referenciando a essa memória (geralmente através do uso de uma variável - se eles tiverem ouvido falar sobre o conceito dos ponteiros de função, eu os usaria como um conceito similar) - esta resposta cobre os princípios básicos (sem mencionar os fechamentos etc), mas pode-se entender facilmente.


Eu gosto da explicação do Lambdas neste artigo: A evolução do LINQ e seu impacto no design do C # . Isso fez muito sentido para mim, pois mostra um mundo real para Lambdas e o constrói como um exemplo prático.

Sua explicação rápida: Lambdas são uma maneira de tratar o código (funções) como dados.


Eu também tenho isso. Eu tentei em JS com este:

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

Ele adiciona 2 a 4, em seguida, mults o resultado por 6. No entanto, acho que às vezes é difícil de ler :(

Também fiz uma função interessante para cada uma delas:

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

Este método irá iterar uma matriz e executa uma ação - no caso de impressão para o console. Agora eu também entendo porque os labmdas são poderosos.


Imagine que você tem um restaurante com uma opção de entrega e você tem um pedido que precisa ser feito em menos de 30 minutos. O ponto é que os clientes geralmente não se importam se você manda sua comida de bicicleta com um carro ou descalço, desde que mantenha a refeição aquecida e amarrada. Então vamos converter este idioma para JavaScript com funções de transporte anônimas e definidas.

Abaixo definimos o caminho de nossa entrega também definimos um nome para uma função:

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

E se usássemos as funções seta / lambda para realizar essa transferência:

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

Você vê que não há diferença para o cliente e não desperdiça tempo para pensar em como enviar comida. Apenas envie.

Btw, eu não recomendo o kebap com coque é por isso que os códigos superiores lhe darão erros. Diverta-se.


Lambda vem do Lambda Calculus e se refere a funções anônimas na programação.

Por que isso é legal? Ele permite que você escreva funções de eliminação rápida sem nomeá-las. Ele também fornece uma boa maneira de escrever encerramentos. Com esse poder você pode fazer coisas assim.

Python

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

Como você pode ver no snippet do Python, o somador da função aceita um argumento x e retorna uma função anônima, ou lambda, que recebe outro argumento y. Essa função anônima permite criar funções a partir de funções. Este é um exemplo simples, mas deve transmitir o poder que os lambdas e os fechamentos têm.

Exemplos em outros idiomas

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

Esquema

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

C # 3.5 ou superior

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

Rápido

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

(\x y -> x + y) 

Java ver este 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

Rubi

Ruby é um pouco diferente, pois você não pode chamar um lambda usando exatamente a mesma sintaxe que chamar uma função, mas ainda tem lambdas.

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

Ruby sendo Ruby, existe uma abreviação para lambdas, então você pode definir o adder dessa maneira:

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

No Javascript, por exemplo, as funções são tratadas como o mesmo tipo misto de todo o resto ( int , string , float , bool ). Assim, você pode criar funções rapidamente, atribuí-las a coisas e chamá-las de volta mais tarde. É útil, mas não é algo que você queira usar em demasia ou você confundirá todos que tiverem que manter seu código depois de você ...

Este é um código com o qual eu estava jogando para ver o quão profundo é esse buraco de coelho:

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

No contexto de CS, uma função lambda é um conceito matemático abstrato que aborda um problema de avaliação simbólica de expressões matemáticas. Nesse contexto, uma função lambda é a mesma que um termo lambda .

Mas nas linguagens de programação é algo diferente. É um pedaço de código que é declarado "in loco" e que pode ser passado como um "cidadão de primeira classe". Esse conceito pareceu ser útil, de modo que chegou a quase todas as linguagens de programação modernas e populares (veja lambda functions everwhere post).


O nome "lambda" é apenas um artefato histórico. Tudo o que estamos falando é uma expressão cujo valor é uma função.

Um exemplo simples (usando o Scala para a próxima linha) é:

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

onde o argumento para o método foreach é uma expressão para uma função anônima. A linha acima é mais ou menos o mesmo que escrever algo assim (código não muito real, mas você terá a ideia):

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

exceto que você não precisa se preocupar com:

  1. Declarando a função em outro lugar (e tendo que procurá-la quando você revisitar o código mais tarde).
  2. Nomeando algo que você está usando apenas uma vez.

Uma vez que você está acostumado a funcionar com valores, ter que passar sem eles parece tão bobo quanto ser necessário para nomear todas as expressões, como:

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

em vez de apenas escrever a expressão onde você precisa:

println(2 * a + b)

A notação exata varia de idioma para idioma; O grego nem sempre é obrigatório! ;-)


Refere-se ao cálculo lambda , que é um sistema formal que apenas possui expressões lambda, que representam uma função que assume uma função para seu único argumento e retorna uma função. Todas as funções no cálculo lambda são desse tipo, ou seja, λ : λ → λ .

Lisp usou o conceito de lambda para nomear seus literais de função anônimos. Este lambda representa uma função que recebe dois argumentos, xey, e retorna seu produto:

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

Pode ser aplicado em linha como este (avalia a 50 ):

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

Um exemplo de um lambda em Ruby é o seguinte:

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

hello.call

Gerará a seguinte saída:

Hello
I am inside a proc

Um lambda é um tipo de função, definido em linha. Juntamente com um lambda, você normalmente também tem algum tipo de variável que pode conter uma referência a uma função, lambda ou outra.

Por exemplo, aqui está um trecho de código C # que não usa um 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);
}

Isso chama a Calculadora, passando não apenas dois números, mas qual método chamar dentro da Calculadora para obter os resultados do cálculo.

No C # 2.0 obtivemos métodos anônimos, o que encurta o código acima para:

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

E então, no C # 3.0, obtivemos lambdas, o que torna o código ainda mais curto:

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







theory