Applicazione parziale
# Applicazione parziale

In matematica e informatica si definisce applicazione parziale di una funzione l'applicazione di una funzione a una parte dei suoi argomenti.

A rigore questa operazione dovrebbe essere "proibita", in quanto una funzione per essere definita deve essere applicata a tutti i suoi argomenti. In realtà ci sono diversi linguaggi di programmazione che consentono di farlo, restituendo un risultato utilizzabile, e anche nell'ambito della matematica è possibile dare un senso a un'espressione in cui una funzione sia applicata a una parte dei suoi argomenti.

## Approccio intuitivo con degli esempi

Prima ancora di fornire la definizione formale, un semplice esempio può mostrare che il significato da dare a un'applicazione parziale è piuttosto intuitivo, al di là delle complicazioni che si pongono quando si voglia formalizzare tale intuizione.

Si supponga di avere una funzione moltiplica che moltiplica due numeri interi, cioè che a ogni coppia di interi fa corrispondere il loro prodotto:

    $moltiplica:\mathbb {N} \times \mathbb {N} \to \mathbb {N}$
    $moltiplica:(m,n)\mapsto moltiplica(m,n)=m\cdot n$

Per definizione, se questa funzione viene applicata a due numeri restituisce un numero. Per esempio $moltiplica(2,3)=6$. Ma si supponga di avere un'espressione come questa: $moltiplica(2,\cdot )$ (dove il punto indica l'assenza di un argomento), o un'espressione come questa: $moltiplica(2)$, cioè un'espressione in cui sia presente uno solo dei due argomenti. Quale significato si potrebbe dare a questa espressione?

Se si usa un'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 $moltiplica(2,\cdot )$ o come $moltiplica(2)$ prende un argomento e restituisce il prodotto di tale argomento con il numero 2:

    $moltiplica(2):\mathbb {N} \to \mathbb {N}$
    $moltiplica(2):n\mapsto moltiplica(2)(n)=2\cdot n$

Intuitivamente la cosa è talmente banale da sembrare quasi un'inutile complicazione formale, nel senso che sembra non esserci bisogno di introdurre ulteriori definizioni per poter porre:

    $moltiplica(m,n)=moltiplica(m)(n)$

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è $moltiplica(m)$, applicata ad un argomento. Tornando all'esempio di poco fa, $moltiplica(2)$ è una funzione, che potremmo definire doppio:

    $doppio=moltiplica(2)$

la quale prende come argomento un numero e restituisce il doppio di quel numero.

Inoltre, poiché per m fissato moltiplica(m) è una funzione, allora nel secondo membro della equazione moltiplica deve essere considerata una funzione di un argomento, che per ogni intero m restituisce una funzione da $\mathbb {N}$ a $\mathbb {N}$. Una tale funzione, che prende un "numero" (in senso generico) e restituisce una funzione è detta anche funzionale. Pertanto quando si applica una funzione a 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 a 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 parzialmente. Altri linguaggi invece richiedono che prima la funzione venga trasformata in un funzionale, e che poi questo funzionale venga applicato a 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, ottenendo 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

Dati tre insiemi A, B e C (eventualmente coincidenti) e una funzione

    $f:A\times B\to C$
    $f:(a,b)\mapsto c=f(a,b)$

ad essa si possono associare in modo "naturale" due funzionali $F_{1}$ e $F_{2}$ definiti in questo modo:

### $F_{1}$

    $F_{1}:A\to \{\phi |\phi :B\to C\}$
    $F_{1}:a\mapsto F_{1}(a):=f(a,\cdot )$
    $F_{1}(a):b\mapsto (F_{1}(a))(b)=f(a,b)$

### $F_{2}$

    $F_{2}:B\to \{\phi |\phi :A\to C\}$
    $F_{2}:b\mapsto F_{2}(b):=f(\cdot ,b)$
    $F_{2}(b):a\mapsto (F_{2}(b))(a)=f(a,b)$

Se aumenta il numero delle variabili la notazione si fa ancora più pesante, e bisogna considerare dei "funzionali a valori funzionali" cioè dei funzionali che applicati ad un loro argomento restituiscono a loro volta un funzionale.

