Programmazione funzionale: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
mNessun oggetto della modifica |
m wikif |
||
Riga 1:
La '''programmazione funzionale''' è un [[w:paradigma di programmazione|paradigma di programmazione]] in cui il flusso di esecuzione del programma assume la forma di una serie di valutazioni di [[w:Funzione (matematica)|funzioni matematiche]]. Solitamente questo approccio viene usato maggiormente in ambiti accademici piuttosto che industriali. Il punto di forza principale di questo paradigma è la mancanza di ''[[w:Effetto collaterale (informatica)|effetti collaterali]]'' (''side-effect'') delle funzioni, il che comporta una più facile verifica della correttezza e della mancanza di [[w:Bug (informatica)|bug]] del programma e la possibilità di una maggiore ottimizzazione dello stesso. Un uso particolare del paradigma, per l'ottimizzazione dei programmi, è quello di trasformare gli stessi per utilizzarli nella [[w:Programmazione concorrente|programmazione parallela]].▼
La programmazione funzionale pone maggior accento sulla definizione di funzioni, rispetto ai paradigmi [[w:Programmazione procedurale|procedurali]] e [[Programmazione imperativa|imperativi]], che invece prediligono la specifica di una sequenza di comandi da eseguire. In questi ultimi, i valori vengono calcolati cambiando lo stato del programma attraverso delle assegnazioni; un programma funzionale, invece, è immutabile: i valori non vengono trovati cambiando lo stato del programma, ma costruendo nuovi stati a partire dai precedenti.▼
{{Categorizzare}}▼
▲La '''programmazione funzionale''' è un [[paradigma di programmazione]] in cui il flusso di esecuzione del programma assume la forma di una serie di valutazioni di [[Funzione (matematica)|funzioni matematiche]]. Solitamente questo approccio viene usato maggiormente in ambiti accademici piuttosto che industriali. Il punto di forza principale di questo paradigma è la mancanza di ''[[Effetto collaterale (informatica)|effetti collaterali]]'' (''side-effect'') delle funzioni, il che comporta una più facile verifica della correttezza e della mancanza di [[Bug (informatica)|bug]] del programma e la possibilità di una maggiore ottimizzazione dello stesso. Un uso particolare del paradigma, per l'ottimizzazione dei programmi, è quello di trasformare gli stessi per utilizzarli nella [[Programmazione concorrente|programmazione parallela]].
▲La programmazione funzionale pone maggior accento sulla definizione di funzioni, rispetto ai paradigmi [[Programmazione procedurale|procedurali]] e [[Programmazione imperativa|imperativi]], che invece prediligono la specifica di una sequenza di comandi da eseguire. In questi ultimi, i valori vengono calcolati cambiando lo stato del programma attraverso delle assegnazioni; un programma funzionale, invece, è immutabile: i valori non vengono trovati cambiando lo stato del programma, ma costruendo nuovi stati a partire dai precedenti.
==Introduzione==
Le
Questo tipo di funzioni hanno zero o più [[w:Parametro (programmazione)|parametri]] e un singolo valore di ritorno. I parametri sono gli input della funzione ed il valore di ritorno è il suo output. La definizione di una funzione descrive come questa deve essere valutata (computata) in termini di altre funzioni. Per esempio, la funzione ''f(x) = x<sup>2</sup> + 2'' è definita in termini delle funzioni di potenza e addizione. Ad un certo punto della serie di chiamate a funzioni, il linguaggio metterà a disposizioni funzioni atomiche, cioè funzioni che non richiamano nessun'altra funzione.
In un linguaggio di programmazione funzionale, le funzioni possono essere manipolate in diversi modi. Solitamente, in questi linguaggi, le funzioni sono entità di ''prima classe'', cioè possono essere passate come parametri ad altre funzioni e possono essere restituite come valori di ritorno da altre funzioni. Ciò permette a funzioni come <tt>mapcar</tt> in [[w:Lisp|Lisp]] e <tt>map</tt> in [[w:Haskell|Haskell]], che prendono una funzione e una lista come input ed applicano la funzione in input ad ogni elemento della lista, di restituire una lista dei risultati. Le funzioni possono avere dei nomi, come in ogni altro linguaggio, o essere definite anonimamente (a volte anche a ''[[w:run-time|run-time]]'') usando l'[[w:Lambda calcolo|astrazione lambda]], e essere usate come valori in altre funzioni.
I linguaggi funzionali permettono inoltre una tecnica chiamata ''currying'', che permette di trasformare una funzione con parametri multipli in una funzione con un solo parametro che mappa ad un'altra funzione con un solo parametro e così via, fino all'esaurimento dei parametri. La funzione trasformata può essere applicata ad un sottoinsieme dei suoi parametri iniziali e dare come risultato una nuova funzione dove i parametri di quel sottoinsieme sono costanti e il resto dei parametri hanno valori non ancora specificati. Infine questa nuova funzione può essere applicata ai parametri rimanenti per ottenere il risultato finale. Per esempio, una funzione <tt>somma(x,y) = x + y</tt> può essere trasformata in modo tale che il valore di ritorno di <tt>somma(2)</tt> (nota che non c'è il parametro y) sia una funzione anonima equivalente alla funzione <tt>somma2(y) = 2 + y</tt>. Questa nuova funzione ha un solo parametro a cui somma 2. Questa tecnica non sarebbe possibile se le funzioni non fossero entità ''di prima classe''.
==Storia==
Il
==Confronto con la programmazione imperativa==
Se paragonata alla programmazione imperativa, può sembrare che la programmazione funzionale manchi di molti costrutti spesso (ma incorrettamente) ritenuti essenziali per un linguaggio imperativo, come il [[w:C (linguaggio)|C]] o il [[w:Pascal (linguaggio)|Pascal]]. Per esempio, nella programmazione funzionale rigorosa, non c'è alcuna esplicita allocazione di memoria o assegnazione di variabile, ma, comunque, queste operazioni avvengono automaticamente quando una funzione è invocata: l'allocazione di memoria avviene per creare lo spazio necessario per i parametri e il valore di ritorno e l'assegnazione avviene per copiare i parametri nel nuovo spazio allocato e per copiare il valore di ritorno alla funzione chiamante. Entrambe le operazioni possono avvenire solo alla chiamata di una funzione e al ritorno da essa e quindi gli effetti collaterali sono eliminati. Eliminando gli effetti collaterali dalle funzioni, si ottiene ciò che viene chiamata ''
Le [[
==Linguaggi di programmazione funzionali==
I programmi ''puramente funzionali'' (cioè quelli che obbligano a rispettare le regole del non-effetto-collaterale, trasparenza referenziale, ecc., a differenza dei linguaggi non puramente funzionali che sono un ibrido tra paradigma funzionale e imperativo) non richiedono variabili e non hanno effetti collaterali e sono di conseguenza automaticamente [[w:thread-safe|thread-safe]]. Solitamente i linguaggi funzionali fanno un uso piuttosto sofisticato dello [[w:stack|stack]].
La programmazione funzionale fa un largo uso della ricorsione e, in alcuni linguaggi come
Inoltre, i linguaggi di programmazione funzionali fanno rispettare la trasparenza referenziale, il che comporta che ''termini uguali possono essere sostituiti con termini uguali'' senza modificare il risultato della computazione. Per esempio, possiamo modificare l'espressione
Line 40 ⟶ 36:
eliminando così l'ulteriore valutazione della funzione radice quadrata.
Per quanto possa sembrare intuitivo, questo non è sempre il caso per i linguaggi imperativi. Per esempio, si consideri la "funzione" <code>getchar()</code> del linguaggio C, che legge un [[w:Carattere (informatica)|carattere]] dallo
z = f(getchar(), getchar());
Line 48 ⟶ 44:
Nei linguaggi di programmazione imperativi, generalmente, gli effetti collaterali nascosti sono la regola, non l'eccezione. Ogni volta che una procedura legge o scrive un valore da/in una variabile globale o condivisa, potenzialmente vi sono degli effetti collaterali nascosti. Questa mancanza di un preciso confine su cosa una funzione può modificare o meno porta ad un aumento della complessità nascosta dei programmi scritti in linguaggi non funzionali.
Rimuovendo questa mancanza di informazioni circa il dominio di una funzione, i linguaggi di programmazione funzionali offrono la possibilità di programmi più puliti che sono più facili da progettare e sottoporre a [[w:debugging|debugging]]. Comunque, questi non sono gli unici vantaggi.
Molti programmatori abituati ai paradigmi imperativi trovano difficile imparare la programmazione funzionale, la quale richiede un approccio nello scrivere i programmi completamente differente. Questa difficoltà insieme al fatto che gli ambienti dei linguaggi funzionali non hanno la stessa quantità di strumenti e librerie disponibili dei linguaggi tradizionali, sono tra le ragioni principali per cui la programmazione funzionale ha avuto poco utilizzo nell'industria del software. I linguaggi funzionali sono rimasti largamente di dominio accademico e hobbystico e quei linguaggi che hanno avuto un maggiore utilizzo sono linguaggi funzionali 'non puri', come l'[[w:Erlang (linguaggio)|Erlang]] e il
==Funzioni di ordine superiore==
Un potente meccanismo spesso utilizzato nella programmazione funzionale è quello delle ''[[
Le funzioni di ordine superiore erano studiate dalla teoria del
Più in generale si può dire che le funzioni di ordine superiore sono parte del
Le funzioni di ordine superiore sono cruciali nel paradigma della [[w:programmazione a livello funzionale|programmazione a livello funzionale]] (da non confondere con la programmazione funzionale, di cui tratta questa voce), che include linguaggi come l'[[w:FP (linguaggio di programmazione)|FP]] di [[w:John Backus|John Backus]] e il [[w:J (linguaggio di programmazione)|J]] di [[w:Kenneth Eugene Iverson|Kenneth Eugene Iverson]].
==Considerazioni sull'efficienza==
Per lungo tempo i linguaggi funzionali sono stati etichettati come linguaggi mangia-risorse, sia in termini di
* alcuni dei primi linguaggi funzionali furono implementati con poca attenzione verso l'efficienza;
* i linguaggi non funzionali guadagnavano velocità, almeno in parte, nel lasciare al programmatore alcuni compiti di livello più basso.
Questi compiti di basso livello erano il [[w:bound checking|bound-checking]], ovvero controllare i valori assunti dagli indici dei [[w:buffer|buffer]] per evitare [[w:overflow]overflow], il [[w:garbage collection|garbage collection]], per la gestione della memoria e simili. Questi compiti sono parti essenziali dei programmi moderni e la loro sbagliata gestione è causa di buona parte dei [[w:bug|bug]] del software, quali [[w:memory leak|memory leak]] e vari tipi di
Proprio per la necessità del mondo informatico moderno di sviluppare programmi velocemente e esenti da bug, anche a scapito di un po' di efficienza, anche i linguaggi imperativi moderni stanno includendo queste tecniche di gestione automatica dei compiti di basso livello. Ciò fa sì che oggi le performance dei linguaggi funzionali e dei linguaggi imperativi convergano. Per programmi che passano la maggior parte del tempo facendo computazioni numeriche, alcuni linguaggi funzionali (come l'[[w:Objective Caml|Ocaml]] e il [[w:Clean (linguaggio di programmazione)|Clean]]) possono avvicinarsi alla velocità del
L'utilizzo della memoria nella programmazione funzionale può essere ottimizzato utilizzando delle
Le espressioni nei linguaggi funzionali possono essere valutate (computate) in due modi diversi: in modo 'rigoroso' (o anche 'eager' o 'strict') o in modo 'pigro' (o 'lazy'). I 'linguaggi rigorosi' computano tutti gli argomenti di una funzione prima di valutare la funzione stessa, mentre i 'linguaggi pigri' computano un argomento solamente quando questo è richiesto. L'
Le performance competitive dei moderni linguaggi funzionali (non puri) come l'
== Linguaggi funzionali ==
L'esempio più vecchio di linguaggio funzionale è il
Altri linguaggio, come per esempio [[w:Ruby|Ruby]], [[w:Python|Python]], [[w:Perl|Perl]] e [[w:Tcl/Tk|TCL]], possono essere usati in stile funzionale, dato che hanno funzioni di ordine superiore e altre
Oggi si sta cercando anche di sviluppare linguaggi di programmazione funzionali [[w:Informatica quantistica|quantistici]], cioè che possano esprimere [[w:Algoritmo quantistico|algoritmi quantistici]]. Alcuni esempi sono il linguaggio di [[w:Peter Selinger|Peter Selinger]] {{en}} [http://scholar.google.com/scholar?hl=it&lr=&q=cache:0bfAXyE4QawJ:www.tcs.informatik.uni-muenchen.de/lehre/SS03/Quanten/papers/sel02.pdf.gz+ qui descritto] ed il linguaggio Haskell-like [[QML (linguaggio di programmazione)|QML]] ({{en}} [http://sneezy.cs.nott.ac.uk/QML/ homepage del progetto]).
== Lezioni correlate ==
Line 105 ⟶ 101:
----
Questo articolo include parti di un articolo inserito su [[Nupedia]] il [[19 giugno]] [[2001]]: reviewed and approved by the Computers group; editor, Michael Witbrock; lead reviewer, Nancy Tinkham; lead copyeditors, Ruth Ifcher and Larry Sanger.
▲{{Categorizzare}}
|