Il calcolo lambda non sembrava astratto. E non riesco a capire il punto


18

La domanda di fondo:

Cosa fa per noi il calcolo lambda che non possiamo fare con le proprietà della funzione di base e la notazione generalmente apprese dall'algebra della scuola media?

Prima di tutto, cosa significa astratto nel contesto del calcolo lambda? La mia comprensione della parola astratto è qualcosa che è separato dal macchinario, il riassunto concettuale di un concetto.

Tuttavia, le funzioni lambda, eliminando i nomi delle funzioni, impediscono un certo livello di astrazione. Per esempio:

f(x) = x + 2
h(x, y) = x + 5 y

Ma anche senza definire il meccanismo di queste funzioni, possiamo facilmente parlare della loro composizione. Per esempio:

1. h(x, y) . f(x) . f(x) . h(x, y) or 
2. h . f . f . h

Possiamo includere gli argomenti se vogliamo, oppure possiamo astrarre completamente per dare una visione d'insieme di ciò che sta accadendo. E possiamo ridurli rapidamente a una singola funzione. Diamo un'occhiata alla composizione 2. Posso avere livelli di dettaglio degli studenti con cui posso scrivere a seconda della mia enfasi:

g = h . f . f . h
g(x, y) = h(x, y) . f(x) . f(x) . h(x, y)
g(x, y) = h . f . f . h = x + 10 y + 4

Eseguiamo quanto sopra con il calcolo lambda, o almeno definiamo le funzioni. Non sono sicuro che sia giusto, ma credo che la prima e la seconda espressione aumentino di 2.

(λuv.u(u(uv)))(λwyx.y(wyx))x

E da moltiplicare per 5y.

(λz.y(5z))

Piuttosto che essere astratto, questo sembra entrare nel meccanismo stesso di ciò che significa aggiungere, moltiplicare, ecc. L'astrazione, nella mia mente, significa livello superiore piuttosto che livello inferiore.

Inoltre, faccio fatica a capire perché il calcolo lambda sia persino una cosa. Qual è il vantaggio di

(λuv.u(u(uv)))(λwyx.y(wyx))x

al di sopra di

h(x) = x + 5 y

o una notazione combinata

Hxy.x+5y

o persino la notazione di Haskell

h x y = x + 5 * y

Ancora una volta, cosa fa per noi il calcolo lambda che non possiamo fare con le proprietà e la notazione della funzione stile f (x) che molti hanno familiarità.


9
È divertente dare un esempio da Haskell, poiché Haskell si basa sul calcolo lambda. Il calcolo lambda non riguarda alcuna notazione particolare. È un modello computazionale, equivalente alle macchine di Turing, in cui "tutto è una funzione".
Yuval Filmus,

2
Sì, mi hanno detto che si basa sul calcolo lambda. La domanda a cui devo ancora vedere una risposta in un modo che per me ha senso è perché haskell si basa sul calcolo lambda anziché sul giusto. . . gli attributi di base delle funzioni che ho imparato alla scuola elementare. Questo è davvero l'essenza di tutta questa domanda.
JDG,

6
"Non viene subito in mente uno scopo" quasi la definizione di "astratto"? :-)
David Richerby,

1
Non direi che è dispregiativo. Tale trattamento delle funzioni è utile attraverso il calcolo. Ma vedo come l'etichettatura come scuola media possa essere così interpretata. Lo aggiusterò.
JDG,

6
Dubito che tu abbia una definizione formale di "notazione della funzione di algebra della scuola media". Se hai una definizione per tali funzioni è probabilmente quella teorica impostata che non ha alcun significato computazionale. Parte del punto del calcolo lambda è comprendere tale notazione secondo i propri termini e, oserei dire, estratto da applicazioni particolari come le funzioni polinomiali o il calcolo.
Derek Elkins lasciò SE il

Risposte:


24

Ci sono molte ragioni per cui il calcolo lambda è così importante.

Una ragione molto importante è che il calcolo lambda ci consente di avere un modello di calcolo in cui le funzioni calcolabili sono cittadini di prima classe.

Non si possono esprimere funzioni di ordine superiore nella lingua dell'algebra della scuola media.

Prendi come esempio l'espressione lambda

λf.λg.λX.f(g(X))

Questa semplice espressione ci mostra che, all'interno del calcolo lambda, la composizione della funzione è essa stessa una funzione. Nell'algebra della scuola media, questo non si esprime facilmente.

Nel calcolo lambda, è molto facile esprimere che una funzione restituirà una funzione come risultato.

Ecco un piccolo esempio. L'espressione (dove qui assumo un calcolo lambda applicato con addizione e costanti intere)

(λf.λg.λX.f((g(X)))(λX.X+2)

ridurrà a

λg.λX.g(X)+2

Si noti inoltre che all'interno del calcolo lambda, le funzioni sono espressioni e non definizioni della forma . Questo ci libera dalla necessità di nominare le funzioni e di distinguere tra una categoria sintattica di espressioni e una categoria sintattica di definizioni.f(X)=e

Inoltre, quando diventa impossibile (o semplicemente notoriamente ingombrante) esprimere funzioni di ordine superiore, si avranno anche problemi nell'assegnare i tipi alle espressioni.

La composizione della funzione ha il tipo polimorfico

α.β.γ.(βγ)((αβ)γ)

nel sistema di tipo Hindley-Milner.

Un punto di forza molto forte per il calcolo lambda è la nozione di calcolo lambda tipizzato . I vari sistemi di tipi per linguaggi di programmazione funzionale come Haskell e la famiglia ML si basano su sistemi di tipi per i calcoli lambda e questi sistemi di tipi offrono forti garanzie sotto forma di teoremi matematici:

Se un programma è ben digitato ed e si riduce alla e residua , allora anche e sarà ben digitata.eee'e'

E se 'ben digitato-, allora e non sarà esporrà alcuni errori.ee

Le prove come corrispondenza dei programmi sono particolarmente degne di nota. L'isomorfismo di Curry-Howard (vedi ad esempio https://www.rocq.inria.fr/semdoc/Presentations/20150217_PierreMariePedrot.pdf ) mostra che esiste una corrispondenza molto precisa tra il calcolo lambda tipicamente digitato e la logica proposizionale intuitiva: per ogni tipo corrisponde una formula logica φ T . Una prova di Phi T corrisponde a un termine lambda di tipo T , e un beta-riduzione di questo corrisponde termine per l'esecuzione di un taglio eliminazione nella prova.TφTφTT

Esorto coloro che ritengono che l'algebra della scuola media sia una buona alternativa al calcolo lambda per sviluppare un resoconto dell'algebra della scuola media di ordine superiore tipicamente polimorficamente insieme a una nozione appropriata di isomorfismo di Curry-Howard. Se riuscissi persino a elaborare un assistente di prova interattivo basato sull'algebra della scuola media che ci consentirebbe di provare i numerosi teoremi che sono stati formalizzati usando assistenti di correzione basati su calcoli lambda come Coq e Isabelle, sarebbe ancora meglio. Vorrei quindi iniziare a utilizzare l'algebra della scuola media e quindi, ne sono certo, molti altri con me.


Questa è un'ottima spiegazione. È utile sapere che funzioni di ordine superiore (come la composizione) e la digitazione sono meglio rappresentate nel calcolo lambda è incoraggiante, anche se ciò facilita le prove e il codice dimostrabile. Non vedo le ramificazioni di gran parte di ciò che hai menzionato e perché la notazione tradizionale è inadeguata (ad esempio, sul non aver bisogno di una sintassi di definizione separata f (x) = e), tuttavia è utile che tu abbia nominato alcuni di questi motivi e dà un'idea di quali aree sono migliorate dal calcolo lambda.
JDG,

Naturalmente è possibile introdurre definizioni locali del modulo ma questi possono già essere espressi nella sintassi del calcolo lambda come ( λ x . e ) e . Il calcolo lambda ci consente di esprimere le funzioni senza doverle nominare, così come si può (nell'algebra della scuola media!) Parlare del numero 4 senza doverle nominare con qualche variabile. permettereX=e'nele(λX.e)e'4
Hans Hüttel,

5

Quando le funzioni vengono descritte per la prima volta ai giovani, vengono essenzialmente identificate con grafici (grafici), o forse con formule; questo è il modo in cui le funzioni sono state comprese storicamente prima dell'avvento delle tendenze formaliste in matematica. Al giorno d'oggi le funzioni, come insegnato nel primo calcolo anno, sono funzioni reali, cioè, le funzioni da a R .RR

Le funzioni nel calcolo lambda sono molto più generali. La definizione esatta dipende dal fatto che il tuo calcolo lambda sia digitato o non tipizzato. Nel puro calcolo lambda non tipizzato tutto è una funzione. Questo è molto più generale delle reali funzioni del calcolo.

Anche i linguaggi procedurali a volte usano idee tratte dal calcolo lambda. La funzione di ordinamento in C accetta come parametro una funzione di confronto , che utilizza per confrontare gli elementi. Il calcolo lambda va molto oltre: le funzioni non solo accettano funzioni come input, ma possono anche emetterle.

Il calcolo lambda è un modello di calcolo equivalente in potenza alle macchine di Turing. È un sistema completo per se stesso. Il calcolo lambda puro non ha "5" o "+" come termini primitivi - possono essere definiti all'interno del calcolo, proprio come "5" e "+" non sono primitivi della teoria degli insiemi. (I linguaggi di programmazione pratica implementano i numeri naturali in modo nativo per motivi di efficienza.)

Ho il sospetto che uno dei motivi per cui non sei impressionato dal calcolo lambda è che le sue idee hanno pervaso così tanto il discorso di programmazione da non sembrare più innovativo.


"Sospetto che uno dei motivi per cui non sei impressionato dal calcolo lambda" Therin sta nella domanda che sto ponendo: che cosa fa il calcolo lambda per noi? In altre parole, quando non usiamo il calcolo lambda, cosa succede. Quando usiamo il calcolo lambda, cosa otteniamo? Se il calcolo lambda era la prima volta che la gente pensava, e se le funzioni stesse potessero crearle, allora è impressionante? Tra i miei programmi iniziali di Python ho creato testi contenenti funzioni che ho successivamente valutato, proprio come delegare il compito di prendere decisioni a un'altra persona. Sembra ovvio?
JDG,

questo prima che sapessi molto di tutto. Pensavo solo che il codice fosse fastidioso da scrivere ripetutamente e che la programmazione mi avrebbe aiutato a generare automaticamente funzionalità, comprese le funzioni stesse.
JDG,

2
Python supporta la programmazione funzionale. I primi linguaggi di programmazione no. Se avessi programmato in FORTRAN, non avresti creato programmi con testo contenente funzioni che in seguito hai valutato. Senza nemmeno accorgertene, hai sfruttato le capacità fornite dalle idee dal calcolo lambda.
Yuval Filmus,

2
Eval ebbe origine nel LISP , che fu fortemente influenzato dal calcolo lambda. Qualcosa del genere non è possibile in FORTRAN, C, COBOL e molti altri linguaggi di programmazione.
Yuval Filmus,

Sì, python supporta la programmazione funzionale --- ma non sono sicuro che l'abilità eval () sia stata ispirata da λCalc --- non λCalc per pensare: voglio generare automaticamente codice che posso valutare in seguito. È come dire che λCalc è tenuto a pensare: "Dirò a Miranda di usare il suo miglior giudizio su come gestire il suo dipartimento" --- in altre parole ottenere una funzione per generare le proprie funzioni. Non è necessario λCalc per pensare alla delega di attività di alto livello. Se vuoi parlare di trarre ispirazione da λCalc, è il punto più appropriato per funzioni lambda, comprensioni, ecc.
JDG,

4

X2XX2

λX.X2X2

ff(X)=X2f

L'uso delle espressioni lambda nei linguaggi di programmazione ha un vantaggio simile; puoi scrivere ciò che la funzione fa proprio lì dove è necessario piuttosto che dover definire una funzione completamente nuova altrove nel tuo programma.

ddXX2ddXX2


θ:VV**

θ(v)(f)=f(v)

Molte persone trovano questa notazione a doppia valutazione confusa e / o inquietante, così come questo uso ricorsivo della definizione puntuale di una funzione. La versione di astrazione lambda

θ=λv.λf.f(v)

non ha questo problema.


Infine, c'è un teorema di assurdità astratte che "il semplice calcolo lambda tipizzato" è sostanzialmente la stessa cosa della "categoria chiusa cartesiana" - quindi se ti capita di voler fare calcoli in una categoria chiusa cartesiana, è probabilmente una buona idea usare semplicemente digitato lambda calcolo per farlo.


Sto tornando a questa domanda e sto trovando questa risposta eccezionale. Grazie. Le risposte qui in generale sono davvero interessanti.
JDG,

4

Dirò in anticipo che non sono un esperto di questo argomento, ma ho trascorso solo un po 'di tempo a studiarlo e una delle cose più affascinanti per me in qualsiasi argomento è la storia dietro di esso. Quindi per me capire un po 'della storia dietro il calcolo lambda aiuta a spiegare perché è utile.

Il breve riassunto è che nei primi anni del 1900 dopo che la teoria degli insiemi ha iniziato a decollare e la matematica è stata ripensata in base agli insiemi, alcuni matematici hanno notato che mentre una definizione di teoria degli insiemi ti consente di affermare che esiste una certa struttura, non ti dicono come per costruirlo e calcolarlo. Quindi le definizioni teoriche impostate non sono costruttive . I matematici iniziarono a chiedersi se esistesse un modo per sviluppare definizioni costruttive che andassero oltre la dimostrazione che qualcosa è e invece dimostrano come è .

Da Wikipedia :

In matematica, una dimostrazione costruttiva è un metodo di dimostrazione che dimostra l'esistenza di un oggetto matematico creando o fornendo un metodo per creare l'oggetto. Ciò è in contrasto con una dimostrazione non costruttiva (nota anche come teorema di esistenza o pura esistenza) che dimostra l'esistenza di un particolare tipo di oggetto senza fornire un esempio.

*

È stato quindi dimostrato che il calcolo lambda e la macchina di Turing potevano entrambi rappresentare qualsiasi funzione calcolabile e sono quindi equivalenti.

In teoria, qualsiasi funzione o concetto matematico può essere codificato in forma di calcolo lambda e calcolato. Ciò significa che il calcolo lambda può essere una base completamente separata per la matematica, sebbene ovviamente estremamente noiosa.

Il calcolo lambda non è "utile", nel senso che non hai intenzione di scrivere codice utilizzandolo, ma costituisce la base per la semantica denotazionale che viene utilizzata per descrivere i programmi e i loro effetti dinamici. Questo è usato nelle discussioni sulla correttezza del programma e sul significato semantico. Ovviamente ha anche fortemente influenzato lo sviluppo di linguaggi di programmazione funzionale, che traggono il loro intero concetto di esecuzione dal calcolo lambda.

Spero possa aiutare.

Modifica da aggiungere: mi è stato appena indicato questo documento che mostra la relazione tra topologia, calcolo lambda e fisica. Sfogliandolo brevemente mi sono imbattuto in questa fantastica affermazione:

Mentre una macchina di Turing può essere vista come un modello idealizzato e semplificato di hardware per computer , il calcolo lambda è più simile a un semplice modello di software . ... Poeticamente parlando, il calcolo lambda descrive un universo in cui tutto è un programma e tutto è dato: i programmi sono dati .

Il punto è che il calcolo lambda è un modello idealizzato di calcolo del software e come tale non è legato a una particolare implementazione in alcun linguaggio di programmazione. Modella il calcolo puro .


Altre informazioni sulla storia: breve storia del calcolo λ nell'enciclopedia della filosofia di Stanford. Hanno più voci di quante si possano elaborare in una vita.
David Tonhofer,


3

Il calcolo lambda non è stato progettato per essere un linguaggio di programmazione. In effetti, è stato creato negli anni '30, decenni prima ancora che avessimo persino dei computer programmabili. Piuttosto, è stato creato come modello formale per lo studio del calcolo, in sé. Se sei deluso dalla facilità con cui esprime il codice o le funzioni matematiche, è perché non è quello che serve.


1
"decenni prima avevamo persino i computer programmabili" - sbagliato. Prima esistevano computer programmabili (se non forse universali) e i primi computer universali furono costruiti negli anni '30.
Raffaello

-2

Il calcolo Lambda esiste in modo da poter creare funzioni anonime (ovvero lambda). Se non si eliminano i nomi delle funzioni, lo spazio dei nomi può essere ingombra e si possono esaurire i nomi delle funzioni disponibili. Ciò è particolarmente importante quando si ha a che fare con le cosiddette "funzioni di ordine superiore" che restituiscono funzioni (o puntatori a funzioni) per ovvie ragioni.

In sostanza, le funzioni lambda sono equivalenti a variabili con ambito locale. La programmazione funzionale senza funzioni lambda è analoga alla programmazione procedurale senza variabili locali, vale a dire un'idea terribile.

"perché il calcolo lambda è persino una cosa" i matematici adorano la ridondanza. Il calcolo lambda viene usato raramente in matematica perché, come hai scoperto, la notazione non è molto utile.

"Se riuscissi persino a elaborare un assistente di correzione interattivo basato sull'algebra della scuola media che ci consentirebbe di provare i numerosi teoremi che sono stati formalizzati usando assistenti di correzione basati sul calcolo lambda come Coq e Isabelle, sarebbe ancora meglio. poi inizia a usare l'algebra della scuola media e quindi, ne sono certo, molti altri con me ". Hai sentito parlare di metamath? Nessun calcolo lambda coinvolto lì, può dimostrare molti dei teoremi di coq / isabelle


A parte alcune opinioni, cosa offre questa risposta?
Raffaello

@Raphael Misinformation. La maggior parte di questa risposta non ha nemmeno senso. Non mancano i nomi. Le "funzioni Lambda" non sono equivalenti a variabili localizzate; questo non ha nemmeno senso. Presumo che ciò significhi fare riferimento let, ma mentre letpuò essere codificato con funzioni anonime, chiaramente non puoi andare dall'altra parte. La programmazione funzionale non richiede "funzioni lambda", ad esempio FP o Sisal di Backus .
Derek Elkins lasciò SE

principalmente volevo pubblicare un commento alla risposta di Hans ma non avevo abbastanza karma. così ho deciso di trasformare il commento in una risposta a tutti gli effetti
sn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.