Applicazione parziale: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Abisys.bot (discussione | contributi)
m →‎Implementazioni specifiche per ogni linguaggio: ., replaced: javascript → JavaScript (2) using AWB
Rimozione ingiustificata di contenuto, revert della modifica 53916248 di 2.226.188.173 (discussione)
Riga 12:
:<math>moltiplica : \N \times \N \to \N</math>
:<math>moltiplica : (m, n) \mapsto moltiplica(m,n) = m \cdot n</math>
 
Per definizione se questa funzione viene applicata a due numeri restituisce un numero. Ad esempio <math>moltiplica(2,3)=6</math>. Ma si supponga di avere una espressione come questa: <math>moltiplica(2,\cdot)</math> (dove il punto indica l'assenza di un argomento), o una espressione come questa: <math>moltiplica(2)</math>, cioè una espressione in cui sia presente uno solo dei due argomenti. Quale significato si potrebbe dare a questa espressione?
 
Se si usa una espressione come questa in certi linguaggi di programmazione che consentono di farlo il programma restituisce una funzione. Intuitivamente si capisce che la funzione che viene restituita è una funzione che "aspetta" il secondo argomento, per poter completare l'operazione. Così la funzione che si è scritta come <math>moltiplica(2,\cdot)</math> o come <math>moltiplica(2)</math> prende un argomento e restituisce il prodotto di tale argomento con il numero 2:
:<math>moltiplica(2) : \N \to \N</math>
:<math>moltiplica(2) : n \mapsto moltiplica(2)(n) = 2 \cdot n</math>
 
Intuitivamente la cosa è talmente banale da sembrare quasi una inutile complicazione formale, nel senso che sembra non esserci bisogno di introdurre ulteriori definizioni per poter porre:
:<math>moltiplica(m,n) = moltiplica(m)(n)</math>
 
In realtà però c'è una notevole differenza concettuale, in quanto al primo membro della equazione compare una funzione di due argomenti, cioè ''moltiplica'', applicata a due argomenti, mentre al secondo membro della equazione compare una funzione di un argomento, cioè <math>moltiplica(m)</math>, applicata ad un argomento. Tornando all'esempio di poco fa, <math>moltiplica(2)</math> è una funzione, che potremmo definire ''doppio'':
:<math>doppio = moltiplica(2)</math>
la quale prende come argomento un numero e restitisce il doppio di quel numero.
 
Inoltre, poiché per ''m'' fissato ''moltiplica''(''m'') è una funzione, allora nel secondo membro della equazione ''moltiplica'' deve essere condiderata una funzione di un argomento, che per ogni intero ''m'' restituisce una funzione da <math>\N</math> a <math>\N</math>. Una tale funzione, che prende un "numero" (in senso generico) e restiuisce una funzione è detta anche [[funzionale]]. Pertanto quando si applica una funzione ad una sola parte dei suoi argomenti tale funzione viene implicitamente ridefinita come il funzionale "naturalmente associato" alla funzione stessa. Anzi, più precisamente come uno dei funzionali associabili, poiché per ogni scelta degli argomenti su cui applicare parzialmente la funzione si ha un diverso funzionale associato.
 
Senza appesantire la notazione definendo un diverso funzionale per ogni possibile combinazione parziale degli argomenti, si può lasciare che sia il contesto a determinarlo, usando una notazione sufficiente a chiarirlo. Così se si scrive ''moltiplica''(2) è chiaro dal contesto che si sta usando ''moltiplica'' come un funzionale che associa ad ogni numero una funzione, dopodiché ''moltiplica''(2) è in particolare la funzione ''doppio'', mentre ''moltiplica''(3) sarebbe la funzione ''triplo'' eccetera.
 
Come si diceva sopra, alcuni linguaggi di programmazione implementano questa "sensibilità al contesto", per cui quando una funzione viene applicata ad una parte soltanto dei propri argomenti il linguaggio tratta la funzione come funzionale e restituisce una funzione, la quale poi può essere applicata agli argomenti restanti, i quali a loro volta possono essere presi tutti assieme o parizialmente. Altri linguaggi invece richiedono che prima la funzione venga trasformata in un funzionale, e che poi questo funzionale venga applicato ad una parte degli argomenti. E siccome in linea di principio ci sono tanti funzionali quante sono le combinazioni possibili degli argomenti, per non appesantire la notazione di solito si compie una scelta "radicale", definendo un operatore che trasforma una funzione in un funzionale che prende gli argomenti "uno alla volta" a cominciare dal primo.
 
Tale operatore è detto '''curry''', e l'operazione corrispondente è detta '''currying''', in onore di [[Haskell Curry]], che ne studiò a lungo l'implementazione. In tali linguaggi di programmazione di fatto l'applicazione parziale di una funzione ai suoi argomenti torna ad essere "proibita"; se ad esempio si ha una funzione ''f'' di tre argomenti, quando non la si voglia applicare subito a tutti e tre gli argomenti, scrivendo ''f''(''x'',''y'',''z''), bisogna prima ridurre la funzione ''f'' al funzionale ''curry''(''f''), e poi applicare tale funzionale al primo argomento, ottendo il funzionale ''curry''(''f'')(''x''), che applicato al secondo argomento dà la funzione ''curry''(''f'')(''x'')(''y''), la quale applicata al terzo argomento restituisce il numero ''curry''(''f'')(''x'')(''y'')(''z''). Questo operatore è sempre implicito nel [[lambda calcolo]], dove ogni funzione di più argomenti si considera un funzionale e gli argomenti vengono presi appunto "uno alla volta" a cominciare dal primo dando come risultato altri funzionali o (arrivati al penultimo argomento) una funzione.
 
==Definizione formale==