# Programmazione dichiarativa

In informatica, la programmazione dichiarativa è un paradigma di programmazione secondo cui la logica della computazione viene espressa senza descrivere il suo controllo di flusso.
Molti linguaggi che applicano questo stile mirano a minimizzare o eliminare eventuali effetti collaterali descrivono che cosa il programma deve compiere in termini dello specifico dominio del problema, piuttosto che descrivere come compierlo sotto forma di una sequenza di primitive; il "come" viene lasciato all'implementazione del linguaggio. Questo è in contrapposizione con la programmazione imperativa, che implementa algoritmi descritti esplicitamente nei loro passaggi.
La programmazione dichiarativa spesso considera i programmi come teorie di logica formale che definiscono un certo spazio logico, all'interno del quale le computazioni sono considerate delle deduzioni. Questo paradigma può permettere una grande semplificazione nella scrittura di programmi di calcolo parallelo.
Alcuni linguaggi dichiarativi comuni sono i linguaggi di interrogazione (come SQL, XQuery), le espressioni regolari, la programmazione logica (come Prolog, Datalog, answer set programming), la programmazione funzionale, e i sistemi di gestione di configurazioni.

## Descrizione

Nel primo significato si intende un programma che descrive a cosa una certa entità assomiglia, piuttosto che prescrivere come un'entità può essere creata. Ad esempio le pagine web HTML sono dichiarative, perché descrivono cosa la pagina dovrebbe contenere — titolo, testo, immagini — ma non come si deve fare per visualizzare la pagina sullo schermo del computer. Altri linguaggi, come il Fortran, il C e Java si basano su un diverso approccio, richiedendo al programmatore di implementare specifici algoritmi esecutivi. In sintesi, i programmi imperativi definiscono in modo esplicito un algoritmo per conseguire uno scopo, mentre i programmi dichiarativi definiscono in modo esplicito soltanto lo scopo da raggiungere, lasciando che l'implementazione dell'algoritmo sia realizzata dal software di supporto (per esempio, un'istruzione select di SQL specifica le proprietà dei dati che devono essere estratti da un database, ma NON i dettagli del processo di estrazione vero e proprio).
Nel secondo significato si intende un programma scritto utilizzando un linguaggio di tipo puramente funzionale, logico, o a vincoli. La locuzione "linguaggio dichiarativo" si applica talvolta all'insieme di queste tipologie di linguaggi di programmazione, presi in gruppo e considerati come antitetici rispetto ai linguaggi imperativi. In una certa misura queste due definizioni si sovrappongono. In particolare la programmazione a vincoli e, in minor misura, la programmazione logica, si focalizzano sulla descrizione delle proprietà della soluzione desiderata (il cosa), lasciando indeterminato l'algoritmo da usare per trovare la soluzione (il come). Tuttavia la maggior parte dei linguaggi a vincoli e logici sono in grado di descrivere gli algoritmi ed i dettagli dell'implementazione dei metodi, e quindi non possono rientrare nella categoria dei dichiarativi veri e propri.
Analogamente, è possibile scrivere programmi in stile dichiarativo anche usando un linguaggio di tipo imperativo, di solito ricorrendo alla tecnica dell'incapsulamento. I dettagli delle operazioni da eseguire sono inglobati all'interno di una libreria o di un framework. Un esempio è JUnit, framework della famiglia Java, che permette, previa una semplice definizione, di registrare i blocchi di programma da testare.
In un programma dichiarativo si definiscono le strutture di dati che possono essere elaborate dagli algoritmi standardizzati dal linguaggio per produrre i risultati desiderati. Un linguaggio dichiarativo, come ogni altro linguaggio, definisce una propria sintassi mediante la quale le parole chiave possono essere combinate, ed una semantica che descrive l'output ottenuto utilizzando una certa sequenza di comandi.

## Linguaggi di programmazione domain-specific

Questi linguaggi, detti anche DSL, sono progettati per rispondere alle esigenze di uno specifico settore di utilizzo, e sono spesso di tipo dichiarativo. Alcuni esempi sono i file di configurazione, i fogli di lavoro, e persino le Email, dove gli header "Da:" e "A:" possono essere considerati come istruzioni da processare. Una limitazione dei DSL è di non rispondere completamente agli enunciati di Turing, nel senso che ci sono cose che questi linguaggi non possono fare (più esattamente: non sono dotati di Turing equivalenza). Per esempio: non si possono usare gli spreadsheet per spedire email, e, per inverso, non si può usare un'email per calcolare il saldo di un conto corrente bancario. Per questa ragione i DSL sono spesso integrati (embedded) all'interno di linguaggi general-purpose. Questo approccio permette al programmatore di usare i DSL per eseguire le operazioni loro specifiche, ed il linguaggio general-purpose per affrontare problemi che sarebbe molto difficile (se non impossibile) risolvere con i DSL. I programmi DSL stand-alone — quelli non integrati nei linguaggi general-purpose — sono solitamente più facili da usare, perché non hanno bisogno di aggiungere le complessità concettuali imposte da un linguaggio general-purpose.

## Esempi

Framework la cui installazione racchiude alcuni aspetti della programmazione dichiarativa:
* JUnit
Linguaggi domain-specific che supportano la programmazione dichiarativa:
* XSLT linguaggio dichiarativo per trasformare documenti XML
* SQL comprende una parte dichiarativa (queries per database relazionali)
* TK Solver
* XForms un formato XML che definisce un modello di data processing per dati in formato XML e interfacce utente per la manipolazione di dati XML, come ad esempio web form.
Linguaggi funzionali/logici/vincolati che supportano la programmazione dichiarativa:
* Funzionali: Erlang, Haskell e Lisp
* Logici: Prolog, Mercury
* Vincolati: Oz, altre estensioni di prolog (come ECLiPSe o SICSTUS)