Paradigmi di Programmazione.
Massimo Maria Ghisalberti - pragmas.org
2014-10-18
Paradigma di programmazione
- In informatica un paradigma di programmazione è uno stile fondamentale di programmazione.
- È un insieme di strumenti concettuali forniti dal linguaggio ed una serie di best practice da usare per la stesura del codice sorgente di un programma.
- I paradigmi di programmazione si differenziano nei concetti e nelle astrazioni usate per rappresentare gli elementi di un programma.
- È possibile identificare un processo ereditario tra i vari paradigmi e quindi un albero genealogico.
Linguaggi di programmazione
- Ogni linguaggio di programmazione viene sviluppato seguendo una idea in qualche modo riconducibile ad un particolare paradigma.
- Esistono linguaggi considerati puri e linguaggi impuri cioè che non seguono in maniera stretta (pura) il paradigma.
- Alcuni linguaggi si ispirano a due o più paradigmi: linguaggi multiparadigma.
Paradigmi più comuni
- Esistono molti paradigmi di programmazione che sono stati pensati e sviluppati nel tempo, alcuni hanno avuto più successo di altri.
- Il successo di una pratica di programmazione è indipendente dalla sua bontà intrinseca, ma deve essere fatto ricadere in più fattori:
- momento storico
- capacità di chi la usa.
- richieste industriali
- visione del futuro.
- management
Programmazione procedurale
- ~1960
- Blocchi di codice esecutivo identificati da un nome.
- I blocchi sono racchiusi in un ambito di visibilità da delimitatori.
- I blocchi possono avere variabili e parametri che sono persi all'uscita.
- I blocchi possono avere valori in uscita.
- Subroutine, procedure, funzioni.
- Fortran, COBOL.
- I linguaggi moderni permettono la scrittura di procedure e funzioni (alcuni come il Pascal le distinguono, altri come il C no).
Programmazione strutturata
- ~1960/1970
- È la base per altri tipi di programmazione imperativa (es: Object Oriented Programming (OOP)).
- Critica del goto e spaghetti code.
- Nata basandosi sul teorema di Corrado Böhm e Giuseppe Jacopini che afferma come si possa scrivere un programma senza goto solo con delle strutture di controllo.
- Strutture di controllo: sequenza (una istruzione dopo l'altra, sequenza imperativa), selezione (if-then-else, operatori ternari ?:, if a tre vie del FORTRAN 2, case/switch), ciclo (while-do, do-until, for-do).
- Sviluppo della applicazione di algoritmi alla programmazione.
- Linguaggi tipizzati.
- Pascal, Ada, Algol, C.
Programmazione modulare
- ~1970
- Suddivisione del programma in parti chiamate moduli.
- I moduli sono indipendenti.
- I moduli sono opachi internamente e possono idealmente vivere a se stanti.
- I moduli hanno una interfaccia per comunicare con l'esterno.
- Modula, Modula-2, Oberon, CLU, Ada, Pascal.
- Linguaggi tipizzati.
- La maggior parte dei linguaggi moderni la permettono in qualche maniera.
Programmazione funzionale 1
- ~1970
- Incentrata sul concetto di funzione nel senso matematico del termine. (dominio (x), codominio (y) e relazione (f): y = f(x)).
- Le funzioni sono valori.
- Trasparenza referenziale (assenza di effetti collaterali, lo stato esterno della funzione non è alterato. Il valore di ritorno dati gli stessi parametri è garantito in qualunque caso).
- La mancanza di effetto collaterale la rende automaticamente thread-safe.
- Ricorsività e funzioni ricorsive, in particolare la tail recursion che limita l'allocazione dello stack ed il recupero del blocco esecutivo.
- Funzioni di ordine superiore (high-order), le funzioni possono prendere funzioni come parametri e restituire funzioni come risultato).
Programmazione funzionale 2
- Funzioni anonime, closure.
- Tipi parametrici.
- Generalized and extended algebraic data type, permette di creare tipi compositi, tipi varianti.
- Currying, funzione con parametri multipli in funzioni con parametri singoli (possibili le partial application o funzioni semiprecalcolate).
- Pattern matching, switch/case on steroids.
Programmazione funzionale 3
- Decomposizione di strutture complesse.
- List/set/for comprehension, map, filter, reduce, collect, ciclo for parametrico.
- Strict o lazy, computazione dei valori e parametri prima della funzione o solo a richiesta.
- Linguaggi tipizzati, inferenza di tipo, dinamici, puri (con Monadi), impuri.
- Lisp, Clojure, Scheme, Racket, Scala, Standard ML, OCaml, F#, Erlang, Elixir, Haskell, Dylan, Ruby (in parte), Python (in parte).
- In forte ascesa. Programmazione parallela più sicura. Reactive programming.
Programmazione object oriented 2
- ~1980
- Estensione della programmazione modulare.
- Definizione di oggetti opachi in grado di interagire tramite messaggi o funzioni (metodi).
- Incapsulamento (separazione tra interfaccia ed implementazione).
- Ereditarietà singola o multipla (creazione di gerarchie genitore e figlio - visibilità dei campi: pubblica o privata, protetta, pubblicata (Object Pascal property - Java Beans)).
- Polimorfismo, la possibilità di utilizzare una classe dalla sua interfaccia, intercambiabilità di classi con identica interfaccia.
Programmazione object oriented 2
- Autoreferenza con le parole chiave this o self.
- Classi, classi astratte, interfacce, istanze.
- Tipi parametrici.
- Simula (1967), Smalltalk, C++, Objective C, Object Pascal, Java (linguaggi per la JVM), C# (linguaggi .NET), Ruby, Python, Eiffel, Ada95/2005/2012, Oberon…
- Linguaggi tipizzati, inferenza di tipo parziale, dinamici.
- È il paradigma sicuramente oggi più utilizzato.
Paradigmi meno comuni
- Programmazione concorrente (Ada, Occam, Erlang, X10, oggi presente in molti linguaggi con librerie di supporto o costrutti nativi).
- Programmazione logica (Prolog).
- Programmazione event driven.
- Design by Contract (Eiffel, D)
- Programmazione a vincoli (constraint) (Prolog).
- Programmazione ad aspetti, AOP (AspectJ, AspectC++).
Multiparadigma
- Utilizzano due o più dei paradigmi citati.
- La maggior parte dei linguaggi odierni ed in sviluppo.
- Scala, OCaml, Elixir, Clojure, Groovy, Ceylon, Kotlin, Xtend, Lua, Ruby, Python, C#, Java, C++11, Rust, X10, D…
Il Futuro
- Sviluppo di linguaggi di programmazione multiparadigma.
- Il paradigma funzionale sarà onnipresente in qualche maniera.
- Inserimento ed evoluzione del Reactive programming e del paradigma concorrente ed asincrono.
- Computazione distribuita.
- Polyglot Programming.
- Evoluzione ulteriore di DSL (Domain Specific Language), linguaggi generalmente non completi utili per risolvere specifiche problematiche.
- Evoluzione di ulteriori paradigmi (per es.: programmazione funzionale quantistica, Haskell-QML http://sneezy.cs.nott.ac.uk/QML/).
- Il limite è solo la fantasia…
Lista linguaggi di programmazione