Programmazione L’attività con cui si predispone l’elaboratore ad eseguire un particolare insieme di azioni su particolari dati, allo scopo di risolvere un problema Dati Input Elaboratore Elettronico Fondamenti di Informatica Risultati Output 2 1 Linguaggio di programmazione Insieme di regole per la descrizione formale di un algoritmo eseguibile da un calcolatore: Lessico (alfabeto): insieme dei termini disponibili Sintassi: forma delle frasi Semantica: significato delle frasi Fondamenti di Informatica 3 Algoritmi, programmi e calcolatori Ogni elaboratore è una macchina in grado di eseguire azioni elementari su oggetti detti DATI L’esecuzione delle azioni è richiesta all’elaboratore tramite comandi elementari chiamati ISTRUZIONI espresse mediante un opportuno formalismo: il LINGUAGGIO DI PROGRAMMAZIONE La formulazione testuale di un algoritmo in un linguaggio comprensibile ad un elaboratore è detta PROGRAMMA Fondamenti di Informatica 4 2 Programma Un programma è un testo scritto in accordo alla sintassi e alla semantica di un linguaggio di programmazione Un programma è la formulazione testuale, in un certo linguaggio di programmazione, di un algoritmo che risolve un dato problema È composto da un numero finito di istruzioni Ogni istruzione descrive una operazione Fondamenti di Informatica 5 Algoritmo e programma Passi per la risoluzione di un problema: Individuazione di un procedimento risolutivo Scomposizione del procedimento in un insieme ordinato di azioni ALGORITMO Rappresentazione dei dati e dell’algoritmo attraverso un formalismo comprensibile dal calcolatore PROGRAMMA Problema Algoritmo Metodo risolutivo Programma Linguaggio di programmazione Fondamenti di Informatica 6 3 Compiti del programmatore Analizzare il problema riducendolo in termini astratti, eliminando ogni componente non indispensabile e formulando un modello del problema. Individuare una strategia risolutiva e ricondurla ad un algoritmo. Codificare l’algoritmo in modo tale da renderlo comprensibile al calcolatore. Fondamenti di Informatica 7 Competenze ed abilità del programmatore Deve essere in grado di capire i problemi e schematizzarli, distinguendone le diverse componenti (dati in input, parametri del problema, dati in output). Deve essere in grado di risolvere problemi mediante un approccio algoritmico, individuando gli aspetti del problema che possano essere risolti reiterando più volte operazioni simili. Fondamenti di Informatica 8 4 Linguaggi di programmazione Classificati rispetto alle caratteristiche principali: potere espressivo che influenza lo stile di programmazione Fondamenti di Informatica 9 Linguaggi: un po’ di storia Albori: Macchine a programma memorizzato, Programmi come dati LinguaggioMacchina Assemblatore FORTRAN (calcolo scientifico) COBOL (Data Processing) Anni ’60: Formalizzazione della sintassi, Strutture a blocchi, implementazione del calcolo ALGOL LISP (LISt Processing) PL/I – ALGOL ‘68 (Linguaggio universale) 5 L’era moderna: Programmazione strutturata, Metodologie, Astrazione, Linguaggi ad alto livello per la programmazione di sistema LISP PASCAL Varie versioni della logica ADA Universale? C PROLOG ML Programmazion e orientata agli oggetti C++ JAVA Paradigmi Per paradigmi di programmazione si intendono i “modi” in cui vengono specificati i programmi Non si tratta tanto del tipo di linguaggio usato, ma del contesto più ampio al quale un certo linguaggio appartiene Parliamo di come viene organizzata la programmazione, con quali caratteristiche: stile, livello di dettaglio, “forma mentis” del programmatore 6 Tipologie di linguaggi 13 Possiamo aggregare i numerosi linguaggi di programmazione esistenti (ad alto livello) sulla base del modello astratto di programmazione che sottintendono e che è necessario adottare per utilizzarli. Linguaggi di programmazione Imperativi Procedurali C, Pascal, Fortran Ad oggetti Dichiarativi Paralleli Funzionali Logici Lisp Prolog C++, Java Fondamenti di Informatica Linguaggi Imperativi 14 permettono di descrivere operazioni più complesse di quelle che l'elaboratore può eseguire direttamente livello di astrazione più alto risalgono agli anni '50 detti di alto livello di tipo imperativo Es: Basic, Fortran, Pascal, C Fondamenti di Informatica 7 Linguaggi Imperativi 15 Caratteristiche: di utilizzo più semplice indipendenti dall'elaboratore purtroppo ancora legati al modello di Von Neumann: ○ i programmi sono ancora una sequenza di istruzioni; l'evoluzione del calcolo è costituita da una variazione dello stato della memoria ○ Eseguono 3 tipi di operazioni: trasferimento dati operazioni aritmetiche alterazione del flusso del programma Fondamenti di Informatica Programmazione imperativa Classico: i programmi sono sequenze di comandi che agiscono sui dati o sull’ordine di esecuzione delle istruzioni. In genere viene studiato per primo ed è per questo che viene percepito come “più naturale” Esempi di linguaggi imperativi: Assembly, FORTRAN, C, COBOL, Pascal Costrutti tipici: assegnamento, cicli, if-thenelse, procedure con passaggio di parametri 8 Programmazione imperativa Il programmatore deve definire tutte le strutture dati e tutti gli algoritmi che operano su di esse Il programma non può gestire strutture dati parziali Meccanismi dinamici e chiamate di sottoprogrammi gestiti (anche se non sempre completamente) dal programmatore ... Linguaggi a Oggetti 18 Favoriscono la modularità ed il riutilizzo del codice Modellazione del problema da risolvere come un insieme di oggetti che si scambiano messaggi Esempi: C++, Java, Smalltalk, Eiffel Fondamenti di Informatica 9 Programmazione orientata agli oggetti I programmi definiscono delle astrazioni (classi) di elementi del dominio di applicazione del programma Le classi contengono informazioni sui dati ma anche il codice per gestirli (in genere di tipo imperativo) Linguaggi Funzionali 20 Non sono legati al modello di Von Neumann ma al concetto di programmazione funzionale Il primo linguaggio funzionale: Lisp (List Processing), fine anni '50 caratteristiche di manipolazione agevole di informazioni di tipo simbolico Fondamenti di Informatica 10 Differenze con i linguaggi imperativi 21 il calcolo è basato sul calcolo di valori e non sull'assegnamento di valori a variabili Il programma è una definizione di funzioni nel senso più matematico del termine basato su valori e non su effetti il risultato è il risultato di una funzione, non l'effetto causato dalla esecuzione di una sequenza di operazioni Ordine superiore: gli argomenti delle funzioni definite possono essere sia valori di tipi primitivi che altre funzioni L’interpete si occupa di valutare, in base alle funzioni di base e a quelle definite, una qualsiasi espressione ben formata Fondamenti di Informatica Programmazione Funzionale: esempio caml #let rec fatt = function # 0 -> 1 # | n -> n * fatt n-1;; fatt: int -> int = <fun> #let rec map = function # [], f -> [] # | (x::Xs), f -> (f x) :: map Xs;; map: ’a list * (’a -> ’b) -> ’b list = <fun> #map [2;0;3] fatt;; - int list = [2; 1; 6] #map [0;3] (function x -> x+1);; - int list = [1;4] 11 Programmazione Funzionale Primo linguaggio funzionale: -calcolo (nucleo della programmazione funzionale) Molto importante soprattutto dal punto di vista teorico (versione non tipata Turingequivalente) Altri linguaggi: Miranda, Haskell, Scheme, Standard ML (varie implementazioni tra cui CAML), LISP Differenze nell’efficienza, nella vastità di librerie, nel tipo di valutazione (lazy vs eager) Programmazione Funzionale Approccio dichiarativo: il programma è una definizione di funzione, il “calcolo” è built-in I linguaggi funzionali possono essere usati come metalinguaggi per definire altri linguaggi ottenendo, da una definizione denotazionale della semantica, anche un interprete (gratis!) Le moderne implementazioni sono piuttosto efficienti 12 Linguaggi Logici 25 Anche qui il formalismo è dichiarativo: i programmi sono definizioni, in questo caso di relazioni e non di funzioni Basati sulla logica obiettivo: formalizzare il ragionamento caratterizzati da meccanismi deduttivi Programmazione: semplice (occorre solo definire la propria conoscenza del problema) avviene tramite una formulazione dichiarativa Esempio: Prolog Fondamenti di Informatica Linguaggi Logici 26 Programmare significa: descrivere il problema con formule del linguaggio interrogare il sistema, che effettua deduzioni sulla base delle definizioni pertanto Il motore di calcolo è un dimostratore di teoremi che cerca di dimostrare un goal (una clausola Horn senza la conseguenza) a partire dalle clausole del programma Il “risultato” viene fuori dagli assegnamenti alle variabili libere del goal che il dimostratore fa durante la visita (con backtracking) dell’albero di dimostrazione per il goal e il programma logico dati Fondamenti di Informatica 13 Programmazione logica Un programma logico è la definizione di un certo numero di predicati della logica del primo ordine Limitazione: la definizione può avvenire solo con clausole Horn definite: p1 ( X 11 , , X n1 ) pk ( X 1k ,, X mk ) q(Y1 ,, Yh ) dove n, m, k , h 0, pi sono simboli di predicato e gli X ij , Yi sono termini di un linguaggio del primo ordine : c, f(X), f(g(a)), g(c)... Programmazione logica: esempio #append([],Ys,Ys). #append([X|Xs],Ys,[X|Zs]) :append(Xs,Ys,Zs). :- sta per ?- append([1,2],[2,4],X). X = [1,2,2,4] ?- append(X,[3],[2,5,3]) X = [2,5] Ma c’è di più! 14 Programmazione logica: esempio ?- append(X,Y,[3,4,5]). X = [], Y=[3,4,5] ; X = [3], Y=[4,5] ... ?- append(X,Y,[3,4|Z]). X = [3], Y = [4|Z] ; X = [3,4], Y = Z Si definiscono relazioni che possono essere usate anche come funzioni, ma non solo! Paradigmi dichiarativi I linguaggi dichiarativi sono molto utili per realizzare velocemente un prototipo di un’applicazione complessa Con poche righe di codice si possono realizzare operazioni molto complesse Il problema principale resta sempre l’efficienza 15 Programmazione con vincoli Nei linguaggi di programmazione con vincoli il motore principale di calcolo è un risolutore di vincoli in un certo dominio Esempio: risolutore di (dis)equazioni lineari e non nel dominio dei numeri reali Si associa bene con la programmazione logica Il programma aggiunge via via vincoli ad un insieme individuando uno spazio di soluzioni sempre più piccolo oppure vuoto Programmazione concorrente Un programma concorrente consiste di diversi processi che cooperano in un ambiente per raggiungere un risultato comune I processi possono avere meccanismi diversi di comunicazione (canali, memoria condivisa, multi-insieme di vincoli) L’attenzione della programmazione concorrente non è sul calcolo che effettuano i singoli processi, ma sulle loro interazioni 16 Programmazione concorrente Numerosi formalismi possibili: Algebre di processi: CCS, CSP Set di costrutti concorrenti che si aggiungono a linguaggi classici: Linda, Pascal o C concorrenti Programmazione concorrente con vincoli La formalizzazione è importante per effettuare verifiche formali di proprietà (es. mutua esclusione, raggiungibilità di stati, invarianze) sui programmi concorrenti Linguaggio Macchina Insieme di istruzioni eseguibili dalla CPU Dipende dalla CPU: cablata al suo interno, ogni istruzione genera una sequenza di segnali di controllo Linguaggio di basso livello si può accedere direttamente alle funzionalità di base del calcolatore Fondamenti di Informatica 34 17 Linguaggio Macchina Complesso da utilizzare: ogni istruzione esegue un'operazione semplicissima esistono librerie con procedure generali Gli altri linguaggi vengono “convertiti” in sequenze di istruzioni in linguaggio macchina Fondamenti di Informatica 35 Linguaggio Macchina Il Linguaggio Macchina è estremamente efficiente I programmi sono: più veloci più corti … ma più complessi Fondamenti di Informatica 36 18 Linguaggi - basso livello Il linguaggio macchina specifica solo le operazioni che l'elaboratore può eseguire sintattica molto elementare" diverso per ogni processore ○ dipende dalle caratteristiche architetturali della CPU E' più orientato alla macchina che ai problemi da trattare è infatti definito di "basso livello“ Le istruzioni devono essere espresse come sequenze di bit! Fondamenti di Informatica 37 Linguaggio Macchina La scrittura è complessa: istruzioni formate da stringhe di 1 e 0: quindi è necessario un insieme di simboli (Linguaggio Assembly) per referenziare le locazioni di memoria è necessario avere delle etichette necessario commentare ogni istruzione Fondamenti di Informatica 38 19 Linguaggi - basso livello Una prima evoluzione è stata l'introduzione di linguaggi simbolici: linguaggi assemblativi (assembly) ancora orientati alla macchina e non ai problemi più immediati da utilizzare definiscono variabili, simboli,... Fondamenti di Informatica 39 Linguaggi - alto livello Altri linguaggi sono basati su: la descrizione del problema in modo intuitivo, dimenticandosi che verranno eseguiti da un calcolatore obiettivo: fornire un mezzo espressivo per specificare all'elaboratore il compito da eseguire Fondamenti di Informatica 40 20 Linguaggi - alto livello Caratteristiche: ognuno ha i propri paradigmi che garantiscono forme espressive appropriate per alcuni problemi specifici questa specificità ha favorito la loro proliferazione (fenomeno intrinseco alla natura del linguaggio come forma di comunicazione) Fondamenti di Informatica 41 Linguaggi La programmazione a basso livello è più ardua e meno intuitiva, ma consente di sviluppare programmi efficienti. Ad alto livello la programmazione è più “naturale” e rapida, ma è possibile che non consenta di produrre software efficiente. Efficienza del programma Programmazione a basso livello Programmazione ad alto livello Facilità e velocità di programmazione Fondamenti di Informatica 42 21 Traduzione dei programmi Affinchè un programma scritto in un qualsiasi linguaggio di programmazione sia comprensibile (e quindi eseguibile) da un calcolatore, occorre tradurlo dal linguaggio originario al linguaggio della macchina Questa operazione viene normalmente svolta da speciali programmi detti traduttori Fondamenti di Informatica 43 Traduzione di un programma Il traduttore converte: Il testo di un programma scritto in un particolare linguaggio di programmazione (sorgente) … … nella corrispondente rappresentazione in linguaggio macchina (programma eseguibile) sorgente … X=X+1; If X>0 … … traduzione Fondamenti di Informatica eseguibile 0010100 … 01001.. 10010… 44 22 Compilatori e Interpreti Esistono due categorie di traduttori: i compilatori: traducono l’intero programma (senza eseguirlo) e producono in uscita il programma convertito in linguaggio macchina gli interpreti: traducono ed eseguono immediatamente ogni singola istruzione del programma sorgente Fondamenti di Informatica 45 Interprete L’ interprete: itera più volte questo processo Legge un’istruzione del programma “sorgente” Traduce l’istruzione in linguaggio macchina Esegue l’istruzione Passa all’interpretazione dell’istruzione successiva Al termine di questa operazione, del programma in linguaggio macchina non rimane alcuna traccia (la traduzione non viene memorizzata) Se il programma torna più volte su una stessa istruzione, questa verrà tradotta (ed eseguita) ogni volta. È necessario disporre dell’interprete per poter eseguire il programma. Fondamenti di Informatica 46 23 Compilatore Compilatore: esegue una sola volta il processo Legge tutte le istruzioni del programma “sorgente” e le traduce in linguaggio macchina. Memorizza su disco il programma “eseguibile” tradotto in linguaggio macchina. Al termine della compilazione avremo un programma eseguibile in linguaggio macchina. La traduzione di ogni istruzione del programma avviene una sola volta, anche se una stessa istruzione viene ripetuta più volte all’interno del programma. Non ho bisogno di avere il compilatore ed il sorgente per eseguire il programma: mi basta il programma eseguibile Fondamenti di Informatica 47 Compilatori e Interpreti sorgente … X=X+1; If X>0 … … traduzione eseguibile 0010100 … 01001.. 10010… esecuzione Nel caso del compilatore, lo schema precedente viene percorso una volta sola, prima dell’esecuzione Nel caso dell’interprete, lo schema viene invece attraversato tante volte quante sono le istruzioni che compongono il programma Fondamenti di Informatica 48 24 Compilatori e Interpreti Tipicamente, l’esecuzione di un programma compilato è più veloce dell’esecuzione di un programma interpretato Fondamenti di Informatica 49 Esecuzione dei programmi Nel caso dei compilatori, l'esecuzione di un programma scritto con un linguaggio ad alto livello è preceduta dai seguenti passi: 1. traduzione in linguaggio macchina 2. collegamento con programmi di supporto (calcoli, comunicazione con periferiche,…) 3. caricamento in memoria Fondamenti di Informatica 50 25 Traduzione in linguaggio macchina: compilatore Viene suddivisa in 2 passi: analisi (lessicale, grammaticale, contestuale) trasformazione del programma sorgente in programma oggetto (forma più vicina al linguaggio macchina): ○ creazione tabella simboli ○ ottimizzazioni (rimozione ripetizioni, eliminazione cicli, sfruttamento registri,…); livelli di ottimizzazione Fondamenti di Informatica 51 Collegamento con programmi di supporto linker Il codice oggetto così formato: può ancora contenere dei simboli irrisolti ○ riferimenti esterni a programmi di servizio (accesso alle periferiche, calcoli matematici,...) contiene indirizzi relativi Il linker serve per collegare diversi moduli oggetto, e formare un unico programma eseguibile Fondamenti di Informatica 52 26 Caricamento in memoria: loader Il Loader serve per caricare in memoria un programma Nel caricamento vengono fissati tutti gli indirizzi relativi variabili, salti, … Vengono caricati anche i moduli di supporto, se necessari Fondamenti di Informatica 53 Costruzione “manuale” In passato, la costruzione dell’eseguibile si faceva “a mano”, attivando compilatore e linker dalla linea di comando del sistema operativo (DOS, Unix, ...) C:\PROVA> gcc -c f1.c (genera f1.obj) C:\PROVA> ld -o prog.exe f1.obj –lc (genera prog.exe) Eseguibile da produrre File Libreria di oggetto Fondamenti di Informatica sistema C 54 27 Ambienti Integrati Oggi, gli ambienti di lavoro integrati (IDE – Integrated Development Environments) automatizzano la procedura: compilano i file sorgente (se e quando necessario) invocano il linker per costruire l’eseguibile ma per farlo devono sapere: quali file sorgente costituiscono l’applicazione il nome dell’eseguibile da produrre. Fondamenti di Informatica 55 28