Domanda

Per una persona senza competenze in ambito scientifico, cos'è una lambda nel mondo dell'informatica?

È stato utile?

Soluzione

Lambda deriva da Calcolo Lambda e si riferisce a funzioni anonime nella programmazione.

Perché è bello?Ti consente di scrivere funzioni rapide da eliminare senza nominarle.Fornisce anche un bel modo per scrivere le chiusure.Con quel potere puoi fare cose del genere.

Pitone

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

Come puoi vedere dallo snippet di Python, il sommatore di funzioni accetta un argomento x e restituisce una funzione anonima, o lambda, che accetta un altro argomento y.Quella funzione anonima ti consente di creare funzioni da funzioni.Questo è un esempio semplice, ma dovrebbe trasmettere il potere che hanno lambda e chiusure.

Esempi in altre lingue

Perl5

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

schema

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

C# 3,5 o versione successiva

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

Veloce

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) 

Giava Vedere questo 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

Rubino

Ruby è leggermente diverso nel senso che non puoi chiamare una lambda utilizzando la stessa identica sintassi della chiamata di una funzione, ma ha comunque delle lambda.

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

Essendo Ruby Ruby, esiste una scorciatoia per lambda, quindi puoi definirlo adder Da questa parte:

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

Altri suggerimenti

Una lambda è un tipo di funzione, definita inline.Insieme a una lambda di solito hai anche un tipo di variabile che può contenere un riferimento a una funzione, lambda o altro.

Ad esempio, ecco un pezzo di codice C# che non utilizza un 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);
}

Questo chiama Calcolatrice, trasmettendo non solo due numeri, ma anche quale metodo chiamare all'interno di Calcolatrice per ottenere i risultati del calcolo.

In C# 2.0 abbiamo metodi anonimi, che abbreviano il codice sopra in:

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 poi in C# 3.0 abbiamo lambda che rendono il codice ancora più breve:

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

Si riferisce a calcolo lambda, che è un sistema formale che ha solo espressioni lambda, che rappresentano una funzione che accetta una funzione come unico argomento e restituisce una funzione.Tutte le funzioni nel lambda calcolo sono di questo tipo, cioè λ : λ → λ.

Lisp ha utilizzato il concetto lambda per denominare le sue funzioni letterali anonime.Questa lambda rappresenta una funzione che accetta due argomenti, x e y, e restituisce il loro prodotto:

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

Può essere applicato in linea in questo modo (valuta a 50):

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

Il nome "lambda" è solo un artefatto storico.Tutto ciò di cui stiamo parlando è un'espressione il cui valore è una funzione.

Un semplice esempio (usando Scala per la riga successiva) è:

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

dove l'argomento a foreach Il metodo è un'espressione per una funzione anonima.La riga sopra è più o meno la stessa cosa che scrivere qualcosa di simile (codice non proprio reale, ma avrai un'idea):

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

tranne che non devi preoccuparti di:

  1. Dichiarare la funzione da qualche altra parte (e doverla cercare quando si rivisita il codice in seguito).
  2. Dare un nome a qualcosa che usi solo una volta.

Una volta che sei abituato ai valori delle funzioni, doverne fare a meno sembra tanto sciocco quanto dover nominare ogni espressione, come ad esempio:

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

invece di scrivere semplicemente l'espressione dove ti serve:

println(2 * a + b)

La notazione esatta varia da lingua a lingua;Il greco non è sempre richiesto!;-)

Il lambda calcolo è una teoria matematica coerente della sostituzione.Nella matematica scolastica si vede ad esempio x+y=5 accoppiato con x−y=1.Oltre ai modi per manipolare le singole equazioni, è anche possibile mettere insieme le informazioni di queste due, a condizione che le sostituzioni delle equazioni incrociate vengano eseguite in modo logico.Il lambda calcolo codifica il modo corretto di eseguire queste sostituzioni.

Dato che y = x−1 è una riorganizzazione valida della seconda equazione, questa: λ y = x−1 significa una funzione che sostituisce i simboli x−1 per il simbolo y.Ora immagina di candidarti λ y a ciascun termine della prima equazione.Se un termine è y quindi effettuare la sostituzione;altrimenti non fare nulla.Se lo fai su carta vedrai come applicarlo λ y renderà risolvibile la prima equazione.

Questa è una risposta senza alcuna informatica o programmazione.

L'esempio di programmazione più semplice a cui riesco a pensare viene da http://en.wikipedia.org/wiki/Joy_(programming_lingual)#How_it_works:

Ecco come la funzione quadrata potrebbe essere definita in un linguaggio di programmazione imperativo (C):

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

La variabile X è un parametro formale che viene sostituito dal valore effettivo da alloggiare quando viene chiamata la funzione.In un linguaggio funzionale (schema) la stessa funzione verrebbe definita:

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

Questo è diverso in molti modi, ma utilizza ancora il parametro formale X allo stesso modo.


Aggiunto: http://imgur.com/a/XBHub

lambda

Leggermente semplificato:una funzione lambda è quella che può essere passata ad altre funzioni e alla sua logica si accede.

In C# la sintassi lambda viene spesso compilata in metodi semplici allo stesso modo dei delegati anonimi, ma può anche essere scomposta e letta la sua logica.

Ad esempio (in C#3):

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

LinqToSql può leggere quella funzione (x > 15) e convertirla nell'SQL effettivo da eseguire utilizzando gli alberi delle espressioni.

L'affermazione sopra diventa:

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

Questo è diverso dai metodi normali o dai delegati anonimi (che in realtà sono solo magia del compilatore) perché non possono esserlo Leggere.

Non tutti i metodi in C# che utilizzano la sintassi lambda possono essere compilati in alberi delle espressioni (ad esempioeffettive funzioni lambda).Ad esempio:

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

Ora l'albero delle espressioni non può essere letto: SomeComplexCheck non può essere scomposto.L'istruzione SQL verrà eseguita senza dove e ogni riga nei dati verrà inserita SomeComplexCheck.

Le funzioni Lambda non devono essere confuse con i metodi anonimi.Ad esempio:

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

Anche questo ha una funzione 'inline', ma questa volta è solo magia del compilatore: il compilatore C# la suddividerà in un nuovo metodo di istanza con un nome generato automaticamente.

I metodi anonimi non possono essere letti e quindi la logica non può essere tradotta come avviene per le funzioni lambda.

Mi piace la spiegazione di Lambda in questo articolo: L'evoluzione di LINQ e il suo impatto sulla progettazione di C#.Per me aveva molto senso in quanto mostra un mondo reale per Lambda e lo costruisce come esempio pratico.

La loro rapida spiegazione:I lambda sono un modo per trattare il codice (funzioni) come dati.

Un esempio di lambda in Ruby è il seguente:

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

hello.call

Genererà il seguente output:

Hello
I am inside a proc

@Brian Utilizzo sempre lambda in C#, negli operatori LINQ e non LINQ.Esempio:

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

Prima di C#, utilizzavo funzioni anonime in JavaScript per i callback alle funzioni AJAX, prima ancora che il termine Ajax fosse coniato:

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

La cosa interessante con la sintassi lambda di C#, tuttavia, è che da sola il loro tipo non può essere dedotto (ovvero, non puoi digitare var foo = (x,y) => x * y) ma a seconda del tipo assegnati, verranno compilati come delegati o alberi di sintassi astratti che rappresentano l'espressione (che è il modo in cui i mappatori di oggetti LINQ eseguono la loro magia "integrata nel linguaggio").

I lambda in LISP possono anche essere passati a un operatore di quotazione e quindi attraversati come un elenco di elenchi.Alcune macro potenti sono realizzate in questo modo.

La domanda ha una risposta formale molto ampia, quindi non cercherò di aggiungere altro al riguardo.

In modo molto semplice, informale parole a qualcuno che sa molto poco o niente di matematica o programmazione, la spiegherei come una piccola "macchina" o "scatola" che riceve degli input, fa un po' di lavoro e produce degli output, non ha un nome particolare, ma sappiamo dove lo è e proprio grazie a questa conoscenza lo usiamo.

In pratica, a una persona che sa cos'è una funzione, direi che si tratta di una funzione senza nome, solitamente collocata in un punto della memoria che può essere utilizzata semplicemente facendo riferimento a quella memoria (di solito tramite l'uso di una variabile - se hanno sentito parlare del concetto di puntatori a funzione, li userei come un concetto simile) - questa risposta copre le nozioni di base (nessuna menzione di chiusure, ecc.) ma si può capire facilmente il punto.

Puoi considerarla come una funzione anonima: ecco alcune informazioni in più: Wikipedia - Funzione anonima

Solo perché non riesco a vedere un esempio C++11 qui, andrò avanti e pubblicherò questo bell'esempio da Qui.Dopo la ricerca, è l'esempio specifico della lingua più chiaro che ho trovato.

Ciao, Lambdas, versione 1

template<typename F>

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

Ciao, Lambdas, versione 2:

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

Ho difficoltà a comprendere le espressioni lambda perché lavoro in Visual FoxPro, che ha la sostituzione delle macro e le funzioni ExecScript{} e Evaluate(), che sembrano avere più o meno lo stesso scopo.

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

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

Un vantaggio decisivo nell'utilizzo di lambda formali è (presumo) il controllo in fase di compilazione:Fox non saprà se hai digitato la stringa di testo sopra finché non tenterà di eseguirla.

Ciò è utile anche per il codice basato sui dati:è possibile memorizzare intere routine nei campi memo del database e quindi valutarle semplicemente in fase di esecuzione.Ciò ti consente di modificare parte dell'applicazione senza avere effettivamente accesso alla fonte.(Ma questo è tutto un altro argomento.)

Per una persona senza competenze in ambito scientifico, cos'è una lambda nel mondo dell'informatica?

Lo illustrerò intuitivamente passo dopo passo in codici Python semplici e leggibili.

In breve, una lambda è solo una funzione anonima e inline.

Partiamo dal compito per capire lambdas come matricola con conoscenze di aritmetica di base.

Il modello di assegnazione è "nome = valore", vedere:

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

'x', 'y' sono nomi e 1, 'valore' sono valori.Prova una funzione in matematica

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

Segnalazioni di errori,
non è possibile scrivere un valore matematico direttamente come codice, "n" dovrebbe essere definito o assegnato a un valore.

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

Adesso funziona, cosa succede se insisti a combinare le due linee separate in una sola?Arriva lambda

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

Nessun errore segnalato.

Questo è uno sguardo lambda, ti permette di scrivere una funzione su una sola riga come fai in matematica direttamente nel computer.

Lo vedremo più tardi.

Continuiamo ad approfondire il tema dei "compiti".

Come illustrato sopra, il simbolo di uguale = funziona con il tipo di dati semplici (1 e 'valore') e l'espressione semplice (n**2 + 2*n + 1).

Prova questo:

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

Funziona con istruzioni semplici, ce ne sono 11 tipi in Python 7.Istruzioni semplici: documentazione di Python 3.6.3

Che ne dici di un'affermazione 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

Arriva def abilitarlo al funzionamento

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

Tada, analizzalo, 'm' è il nome, 'n**2 + 2*n + 1' è il valore.: è una variante di '='.
Trovalo, anche solo per capire, tutto inizia dall'incarico e tutto è incarico.

Ora torna a lambda, abbiamo una funzione denominata 'm'

Tentativo:

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

Ci sono due nomi di 'm' qui, funzione m ha già un nome, duplicato.

Si sta formattando come:

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

Non è una strategia intelligente, quindi segnala gli errori

Dobbiamo eliminarne uno, impostare una funzione senza nome.

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

Si chiama "funzione anonima"

Insomma,

  1. lambda in una funzione in linea che consente di scrivere una funzione in una linea retta come in matematica
  2. lambda è anonimo

Spero che questo ti aiuti.

È una funzione che non ha nome.Per es.in C# puoi usare

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

per restituire i numeri maggiori di 5.

number => number > 5

è la parte lambda qui.Rappresenta una funzione che accetta un parametro (numero) e restituisce un valore booleano (numero > 5).Il metodo GetMatchingItems utilizza questo lambda su tutti gli elementi della raccolta e restituisce gli elementi corrispondenti.

In Javascript, ad esempio, le funzioni vengono trattate come lo stesso tipo misto di tutto il resto (int, string, float, bool).Pertanto, puoi creare funzioni al volo, assegnarle alle cose e richiamarle in seguito.È utile ma non qualcosa che vuoi usare eccessivamente o confonderai tutti coloro che devono mantenere il tuo codice dopo di te...

Questo è un codice con cui stavo giocando per vedere quanto è profonda questa tana del coniglio:

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

Nel contesto della CS una funzione lambda è un concetto matematico astratto che affronta un problema di valutazione simbolica delle espressioni matematiche.In quel contesto una funzione lambda è la stessa di a termine lambda.

Ma nei linguaggi di programmazione è qualcosa di diverso.È un pezzo di codice che viene dichiarato "in atto" e che può essere passato in giro come "cittadino di prima classe".Questo concetto si è rivelato utile tanto da essere presente in quasi tutti i linguaggi di programmazione moderni più diffusi (vedi funzioni lambda ovunque inviare).

Ho capito anch'io.L'ho provato in JS con questo:

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

Somma 2 a 4 quindi moltiplica il risultato per 6.Tuttavia a volte trovo difficile leggere :(

Inoltre ho creato un'interessante funzione 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);

Questo metodo ripeterà un array ed eseguirà un'azione, nel caso stampando sulla console.Ora anch'io capisco perché i labmda sono potenti.

Nella programmazione informatica, lambda è un pezzo di codice (istruzione, espressione o un gruppo di essi) che prende alcuni argomenti da una fonte esterna.Non deve essere sempre una funzione anonima: abbiamo molti modi per implementarle.

Abbiamo una chiara separazione tra espressioni, asserzioni e funzioni, che i matematici non hanno.

Anche la parola "funzione" nella programmazione è diversa: abbiamo "funzione è una serie di passaggi da eseguire" (dal latino "eseguire").In matematica si tratta di correlazione tra variabili.

I linguaggi funzionali cercano di essere il più simili possibile alle formule matematiche e le loro parole hanno quasi lo stesso significato.Ma in altri linguaggi di programmazione la situazione è diversa.

UN Lambda Function, o a Small Anonymous Function, è un blocco di funzionalità autonomo che può essere passato e utilizzato nel codice.Lambda ha nomi diversi in diversi linguaggi di programmazione – Lambda In Pitone E Kotlin, Closure In Veloce, O Block In C E Obiettivo-C.Sebbene il significato di lambda sia abbastanza simile per queste lingue, a volte presenta lievi distinzioni.

Vediamo come funziona Lambda (Closure) in Swift 4.2 con il metodo sorted() – dalla funzione normale fino all'espressione più breve:

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

1.Funzione normale

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


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

2.Espressione di chiusura

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

3.Espressione di chiusura in linea

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

4.Dedurre il tipo dal contesto

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

5.Restituzioni implicite da chiusure a espressione singola

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

6.Nomi degli argomenti in forma abbreviata

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

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

7.Metodi dell'operatore

reverseOrder = coffee.sorted(by: >)

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

Spero che questo ti aiuti.

La domanda ha avuto risposta completa, non voglio entrare nei dettagli.Voglio condividere l'utilizzo durante la scrittura di calcoli numerici in ruggine.

C'è un esempio di lambda (funzione anonima)

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

Quando stavo scrivendo un modulo del metodo Newton-Raphson, è stato utilizzato come derivata del primo e del secondo ordine.(Se vuoi sapere cos'è il metodo Newton-Raphson, visita "https://en.wikipedia.org/wiki/Newton%27s_method".

L'output è il seguente

println!("f={:.6}      df={:.6}", f(10.0), df(10.0))

f=98.000000       df=20.000000

Immagina di avere un ristorante con un'opzione di consegna e di avere un ordine da completare in meno di 30 minuti.Il punto è che ai clienti di solito non importa se gli mandi il cibo in bicicletta con un'auto o a piedi nudi, purché mantieni il pasto caldo e legato.Quindi convertiamo questo idioma in Javascript con funzioni di trasporto anonime e definite.

Di seguito abbiamo definito il modo in cui forniamo, ovvero definiamo un nome per una funzione:

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

E se utilizzassimo le funzioni freccia/lambda per eseguire questo trasferimento:

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

Vedi, non c'è differenza per il cliente e non si perde tempo a pensare a come inviare il cibo.Basta inviarlo.

A proposito, non consiglio il kebap con la coca cola, ecco perché i codici superiori ti daranno errori.Divertiti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top