Paradigmi di Programmazione.

Massimo Maria Ghisalberti - pragmas.org

massimo.ghisalberti@pragmas.org

2014-10-18

Indice

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