Parte 1




                 Tipizzazione dei dati
                   p




Linguaggi dinamici – A.A. 2009/2010
                                         1
Entità di un programma
T   In un programma, ad ogni entità è associato:
     T Nome, identificatore unico nel programma (o in

         una porzione)
     T   Tipo, per indicare l insieme dei valori e delle
                             l'insieme
         operazioni
     T   Valore, tra quelli ammessi dal tipo
     T   Indirizzo, riferimento alla memoria che la
         contiene
     T   Tempo di vita, durata di esistenza nel
         programma
     T   Visibilità (scope) del nome nel programma

Linguaggi dinamici – A.A. 2009/2010
                                                           2
Definizione di tipizzazione
T   Ciascun linguaggio di programmazione è
    dotato di un sistema per la tipizzazione dei dati
T   Tipizzazione dei dati: meccanismo trattabile di
    analisi sintattica che classifica una porzione
    del codice in base ai valori che essa calcola
T   Molto iù i f
    M lt più informalmente: il compilatore cerca
                        l    t          il t
    di capire di che categoria (o tipo) è un valore
    prodotto (type checking)
         d tt (t      h ki )
T   Il tipo caratterizza le operazioni che si possono
    compiere sul valore prodotto, i suoi limiti, la
    sua “precisione”
Linguaggi dinamici – A.A. 2009/2010
                                                        3
Porzioni di codice
T   A quali porzioni di codice viene solitamente
    associato un tipo?
      T   Valori in memoria (costanti)
      T   Variabili
          V i bili semplici
                        li i
      T   Variabili complesse (strutture dati)
      T   Espressioni
T   L'associazione di un tipo di dati ad una
                             p
    porzione di codice informa il compilatore,
    l'interprete ed il programmatore su come tale
           p           p g
    porzione di codice possa essere utilizzata


Linguaggi dinamici – A.A. 2009/2010
                                                    4
Tipi di dato
T   Quali sono i tipi che si possono associare alle
    porzioni di codice?
T   I tipi associabili sono classificabili in due
    distinte categorie
      T   Tipi di dato semplici: caratterizzano un dato
          primitivo, su cui si possono effettuare
            i iti         i i             ff tt
          operazioni “semplici” (numero, caratteri,
          booleani)
      T   Tipi di dato complessi: caratterizzano un dato
          composto da più dati semplici, su cui si
                                 semplici
          possono effettuare operazioni “complesse”
          (stringhe,
          (stringhe struttura dati, classe)
                               dati
Linguaggi dinamici – A.A. 2009/2010
                                                           5
Tipi di dato
T   Esempi di tipi di dato semplici
      T   Int, Integer Float double Char String
          Int Integer, Float, double, Char, String, Boolean
      T   Puntatori
T   Esempi di tipi di dato complessi
      T   Struct, union
      T   Class




Linguaggi dinamici – A.A. 2009/2010
                                                              6
Obiettivi della tipizzazione:
                         Safety
T   L'uso dei tipi permette al compilatore di
    scoprire il più presto possibile (a livello di
    compilazione) codice privo di senso/illecito
T   Si consideri l espressione 3 / “Hi World”
                   l'espressione    Hi World
T   Tale espressione (che non ha alcun senso) è
    scomponibile nel seguente modo:
              ibil      l      t    d
      T   Operando 1: tipo semplice intero 3
      T   Operando 2: tipo stringa “Hi World”
      T   Operatore: divisione /
           p
T   L'operatore divisione non prevede le stringhe!
T   Il compilatore emette un syntax error
Linguaggi dinamici – A.A. 2009/2010
                                                     7
Obiettivi della tipizzazione:
                         Safety
T   Ma attenzione!
T   Si consideri l'espressione ‘a’ / 5
                                 ’
     T   Anche in questo caso non avrebbe senso
         dividere un carattere, ma il C considera questa
         di id           tt                 id        t
         espressione come ASCII(‘a’) / 5
T   Si consideri l'espressione 70 / “2”
     T   È sempre una operazione che potrebbe non
         avere senso, ma un compilatore/interprete
         potrebbe considerarla come 70 / 2 convertendo
         la t i
         l stringa “2” nell’intero che rappresenta
                         ll’i t     h           t
     T   Naturalmente se si ha una generica variabile
         stringa non è detto che rappresenti un numero
Linguaggi dinamici – A.A. 2009/2010
                                                           8
Obiettivi della tipizzazione:
                    Ottimizzazione
T   Le operazioni di type checking, se eseguite in
    uno stadio iniziale (compilazione) possono
    fornire informazioni utilissime
T   Ad esempio, se ad una analisi sintattica segue
        esempio
    l'immediato type checking, si può scoprire che
    una variabile è un puntatore
T   Se tale indirizzo è allineato (su architetture a
    32 bit un multiplo di 4 byte), l'accesso in
        bit,       lti l      b t ) l'        i
    memoria è molto più rapido
T   Sapendo ciò in anticipo, il compilatore può
    utilizzare istruzioni efficienti per accedere al
    dato
Linguaggi dinamici – A.A. 2009/2010
                                                       9
Obiettivi della tipizzazione:
                  Documentazione
T   Nei sistemi di tipizzazione più espressivi, i tipi
    possono servire quale utile fonte di
    documentazione del codice
T   Il tipo di dato illustra la natura di una variabile,
                                              variabile
    ed in ultima analisi l'intento del programmatore
T   Ad esempio, un timestamp (marcatore
                i       ti    t     (      t
    temporale) è, solitamente, un intero a 32/64 bit
T   Dal punto di vista della comprensione del
    codice, è ben diverso leggere int a = 32;
    oppure timestamp a=32;
T   Definizione di nuovi tipi di dato (typedef in C)
                              p         ( yp          )
    per aumentare l'espressività del linguaggio
Linguaggi dinamici – A.A. 2009/2010
                                                           10
Obiettivi della tipizzazione:
                      Astrazione
T   Il meccanismo dei tipi permette di produrre
    programmi ad un livello di astrazione più alto
    di quello nativo della macchina (bit, byte)
T   Ad esempio, una stringa di caratteri può
        esempio
    essere vista a basso livello come una
    sequenza di byte (o di bit)
T   Per l'essere umano, è molto più intuitivo
    pensare ad una stringa come ad una
              d       ti           d
    concatenazione di caratteri
      T   Java: operatore + applicato alle stringhe


Linguaggi dinamici – A.A. 2009/2010
                                                      11
Obiettivi della tipizzazione:
                      Modularità
T   L'uso appropriato dei tipi di dato costituisce
    uno strumento semplice e robusto per definire
    interfacce di programmazione (API)
T   Le funzionalità di una data API sono descritte
    dalle signature (i prototipi) delle funzioni
    pubbliche che la compongono
T   Leggendo tali signature, il programmatore
    (esperto) si fa immediatamente un'idea di cosa
    (      t ) if i      di t       t     'id
    può (o non può) fare



Linguaggi dinamici – A.A. 2009/2010
                                                     12
Un avvertimento
T   Attenzione! I meccanismi che garantiscono le
    proprietà ora viste non sono una panacea!
T   Tali proprietà aiutano a catturare errori di
    natura per lo più sintattica
T   Il meccanismo di tipizzazione (ma anche il
    compilatore, o l'interprete) non può nulla
          il t       l'i t    t )       ò ll
    contro la programmazione sloppy (sciatta) che
    produce errori di natura semantica
        d          i       t        ti
      T   Un ciclo non viene mai terminato
      T   Il flusso del programma è sballato
      T   Una risorsa acquisita non viene mai rilasciata
                          q
Linguaggi dinamici – A.A. 2009/2010
                                                           13
Type checking
T   L'operazione di type checking ha l'obiettivo di
    verificare e di stabilire il tipo di dato associato
    ad una determinata porzione di codice
T   Tale operazione può avvenire:
      T   a tempo di compilazione (compile time)
      T   a tempo di esecuzione (run time)
                           i    (     i )
T   Tale operazione può:
      T   Garantire la non perdita di informazione durante
          le operazioni di conversione
      T   Non garantire la perdita di informazione durante
          le operazioni di conversione
              p
Linguaggi dinamici – A.A. 2009/2010
                                                             14
Type checking statico
T   Un linguaggio di programmazione utilizza un
    meccanismo di type checking statico se le
    operazioni di type checking sono eseguite solo
    a tempo d compilazione
      te po di co p a o e
T   Linguaggi a type checking statico:
      T   C, C++, C#, Java, Fortran,
          C C++ C# Java Fortran Pascal
T   Il type checking statico:
      T   è inteso come una forma primitiva di verifica di
          un programma
      T   permette di individuare parecchi errori con
          largo anticipo (early)
      T   permette una migliore ottimizzazione del codice
Linguaggi dinamici – A.A. 2009/2010
                                                             15
Type checking statico
T   Osservazioni:
      T   i tipi delle espressioni sono determinati durante
          il processo di compilazione
      T   un compilatore non può sapere quali dati avrà
                     il t          ò           li d ti  à
          in ingresso/genererà il programma eseguibile
T   Il t
       type checking statico è conservativo
             h ki       t ti             ti
T   Esempio: if ('A' == 65) printf(“okn”);
T   L'if è vero, tuttavia il solo meccanismo di
    tipizzazione, senza un meccanismo di
      p           ,
    conversione dei tipi, non potrebbe stabilire se
    'A' == 65, e dovrebbe fallire
              ,
Linguaggi dinamici – A.A. 2009/2010
                                                              16
Type checking dinamico
T   Un linguaggio di programmazione utilizza un
    meccanismo di type checking dinamico se la
    maggior parte delle operazioni di type
    c ec g sono eseguite tempo d esecu o e
    checking so o esegu te a te po di esecuzione
T   Linguaggi a type checking dinamico:
      T   Javascript, LISP, Perl, PHP, Python,
          Javascript LISP Perl PHP Python Ruby
T   Il type checking dinamico è più flessibile di
    quello statico
         ll t ti
T   Ad esempio, un programma può costruire
    strutture dati di forma mutevole a run time;
    pertanto, il tipo di dato cambia a run time, e va
    controllato a run time!
Linguaggi dinamici – A.A. 2009/2010
                                                        17
Type checking dinamico
T   Godendo di un meccanismo di tipizzazione a
    run time si possono effettuare gli
         time,
    assegnamenti più strani
T   Ad esempio: $var = <token letto da file>;
T   Il token può avere un qualunque tipo (intero,
    stringa)
      ti    )
T   Il type checker dinamico assegna il tipo
    corretto a run time
T   Provate a scrivere una cosa simile in C!



Linguaggi dinamici – A.A. 2009/2010
                                                    18
Type checking dinamico
T   Ovviamente, la flessibilità si paga
T   Un type checker dinamico dà minori garanzie a
    priori rispetto ad un type checker statico,
    proprio perché non può operare (solamente) a
    tempo di compilazione
T   Se, nell'esempio precedente, $  $var è intesa
    essere una variabile intera che va sommata ad
    un'altra variabile, ed a run time f
                                      fornite una
    stringa, l'interprete non potrà fare altro che
    uscire (con tanti improperi!)
         i (          ii        i!)
T   Il type checker dinamico non poteva sapere
    dell'errore commesso in seguito dall'utente
Linguaggi dinamici – A.A. 2009/2010
                                                     19
Type checking dinamico
T   Un type checker dinamico fa alcuni controlli a
    tempo di compilazione
T   I controlli si limitano alla correttezza sintattica
    degli operatori
T   I controlli a tempo di esecuzione sono, di
    solito, molto più sofisticati, e coinvolgono il
        lit     lt iù fi ti ti          i   l
    processo di identificazione di un tipo di una
    espressione
             i
T   I linguaggi con type checking dinamico hanno
    bisogno di quei controlli che il type checker
    statico potrebbe dare loro
      T   Unit testing
Linguaggi dinamici – A.A. 2009/2010
                                                          20
Type checking statico e dinamico
T   Alcuni linguaggi fanno uso di tecniche di type
    checking statico e dinamico
T   Java:
      T   Checking statico dei tipi
          Ch ki      t ti d i ti i
      T   Checking dinamico (a run time) per le
          operazioni di d
                i i downcasting ( i   (ossia, il casting di
                                          i          i
          una variabile di una classe base in una delle
          sue sottoclassi)




Linguaggi dinamici – A.A. 2009/2010
                                                              21
Pro e contro nella pratica
T   Type checking statico:
      T   Identifica errori a tempo di compilazione (non è
          ben chiaro se ciò aumenta l'affidabilità del
          programma)
      T   Permette la costruzione di codice che esegue
          più velocemente
T   Type checking dinamico:
      T   Permette al compilatore di eseguire i suoi
          compiti molto più velocemente
      T   Permette l'uso di costrutti considerati illegali nei
          linguaggi statici
      T   Permette una più rapida prototipazione
Linguaggi dinamici – A.A. 2009/2010
                                                                 22
Tipizzazione forte
T   Un linguaggio di programmazione adotta una
    tipizzazione forte dei dati se una operazione
    effettuata con operandi aventi tipo di dato non
    co etto e e ped ta
    corretto viene impedita
      T   Un'operazione di somma di interi con caratteri
      T   Un operazione
          Un'operazione in cui si superano i limiti di un
          array
T   Non esiste il linguaggio completamente
    tipizzato in maniera forte
      T   Java è f t
          J      fortemente ti i
                         t tipizzato (più del C e del
                                  t ( iù d l      d l
          Pascal)

Linguaggi dinamici – A.A. 2009/2010
                                                            23
Tipizzazione debole
T   Un linguaggio di programmazione adotta una
    tipizzazione debole dei dati se una operazione
    effettuata con operandi aventi tipo di dato non
    co etto o
    corretto non viene impedita
                   e e ped ta
T   La tipizzazione debole fa spesso uso di
    operatori di conversione (casting) per rendere
    omogenei gli operandi
T   Esempio: var x:= 5; var y:= “37”; x + y;
      T   In alcuni linguaggi (Visual Basic), y viene
          convertito ad intero (x+y=42)
                   tit d i t    ( + 42)
      T   In altri linguaggi (Javascript), x viene convertito
          a stringa (x+y=”537”)
             ti       (   ”537”)
Linguaggi dinamici – A.A. 2009/2010
                                                                24
Tipizzazione safe
T   Un linguaggio di programmazione adotta una
    tipizzazione safe (sicura) dei dati se non
    permette ad una operazione di casting di
    p odu e u
    produrre un risultato erroneo o un crash
                   su tato e o eo u c as
T   Esempio (Visual Basic):
    var x:= 5; var y:= “37”; var z = x + y;
                        37 ;
T   In questo esempio, il risultato è 42
T   L'operazione di conversione non f   fallisce su
    una stringa contenente un intero
T   Se la stringa contenesse “Hi world”, la
    conversione darebbe NULL e z avrebbe un
    valore indefinito (senza crash)
Linguaggi dinamici – A.A. 2009/2010
                                                      25
Tipizzazione unsafe
T   Un linguaggio di programmazione adotta una
    tipizzazione unsafe (non sicura) dei dati se
    permette ad una operazione di casting di
    p odu e u
    produrre un risultato erroneo o un crash
                     su tato e o eo u c as
T   Esempio (C):
    int x= 5; char y [] = “37”; char *z = x + y;
                            37 ;        z
T   Qui, z viene posto all'indirizzo di memoria 5
    byte più in avanti di y
T   Il contenuto di z non è definito, e può trovarsi
    al di fuori dello spazio di indirizzamento del
      l f     i d ll        i    i di i          d l
    processo
T   Una dereferenziazione di z può portare al crash
Linguaggi dinamici – A.A. 2009/2010
                                                       26
Tipizzazione e polimorfismo
T   Con il termine polimorfismo si intende la
    capacità (da parte di un linguaggio) di
    differenziare il comportamento di un metodo o
    d u ope ato e
    di un operatore in funzione dell’entità a cui è
                         u o e de e t tà cu
    applicato
T   Alcuni linguaggi gestiscono il polimorfismo
    anche a livello di tipi di dato
      T   Ad esempio in alcuni linguaggi è possibile definire
             esempio,
          una tabella associativa (tabella hash)
      T   Le chiavi e gli elementi possono essere valori di un
          qualsiasi tipo (o quasi)
      T   Non è necessario predefinire una struttura dati
          apposita per ogni possibile combinazione
Linguaggi dinamici – A.A. 2009/2010
                                                                 27
Parte 1




                              Duck typing
                                    yp g




Linguaggi dinamici – A.A. 2009/2010
                                            28
Tipizzazione classica ad oggetti
T   Nello schema classico di un linguaggio ad
    oggetti,
    oggetti gli attributi ed i metodi a disposizione
    di un oggetto sono:
      T   quelli definiti dalla classe di appartenenza
          dell'oggetto
      T   quelli ereditati dalle superclassi dell oggetto
                                             dell'oggetto
      T   (i metodi) implementati tramite interfacce
T   La l i
    L relazione fra classi va dichiarata
                f    l   i    di hi
    esplicitamente
      T   Parole chiavi (Java) class, extends, interface,
          implements

Linguaggi dinamici – A.A. 2009/2010
                                                            29
Tipizzazione classica ad oggetti
T   In tale schema, individuare il tipo di un
    attributo e/o la signature di un metodo implica:
      T   individuare la classe di appartenenza
          dell oggetto (binding)
          dell'oggetto (binding), con il fine di individuare
          un tipo per l'attributo oppure una signature
          valida per il metodo
      T   In caso di mancata individuazione, ripetere il
          controllo per tutte le superclassi (operation
          dispatching – fino alla classe radice, es. Object)
T   In altre parole individuare un attributo e/o una
             parole,
    signature implica trovare una classe adatta (fra
    quelle imparentate) per l'oggetto
                             l oggetto
Linguaggi dinamici – A.A. 2009/2010
                                                               30
Tipizzazione classica ad oggetti
T   Tali controlli possono essere effettuati
      T   A tempo di compilazione
      T   A tempo di esecuzione
T   Di solito, si preferisce il tempo di compilazione
    (il costo a tempo di esecuzione sarebbe troppo
    elevato)
     T    C++ senza l’uso di puntatori
T   In Java, è fatto a tempo di esecuzione




Linguaggi dinamici – A.A. 2009/2010
                                                        31
Duck typing
T   In un linguaggio di programmazione ad oggetti
    dinamico,
    dinamico basato sul meccanismo di duck
    typing, si rovescia tale concetto
T   Posso evitare di dichiarare esplicitamente la
    dipendenza di una classe da una superclasse
T   Se i t
    S istanzio un oggetto di tale classe ed uso i
              i          tt     t l l       d
    suoi metodi/attributi, l'unica cosa che conta è
    che i metodi/attributi siano definiti
     h       t di/ tt ib ti i     d fi iti
T   Tecnica utilizzata per implementare il
    polimorfismo senza ricorrere alla ereditarietà
T   Attenzione: il meccanismo di ereditarietà
    esiste sempre!
Linguaggi dinamici – A.A. 2009/2010
                                                      32
Duck typing
T   Un type checker basato su duck typing opera
    tipicamente a livello di esecuzione
T   Se vengono referenziati un attributo o un
    metodo di un oggetto, si controlla solamente
                   oggetto
    che il suddetto attributo o metodo siano
    definiti per quell oggetto (duck test)
                 quell'oggetto
      T   Se sono definiti, si accede al dato o si invoca la
          funzione
      T   Se non sono definiti, l'interprete esce con un
          messaggio di errore
                   i
T   Meccanismo molto più snello per il
    compilatore e per il programmatore
Linguaggi dinamici – A.A. 2009/2010
                                                               33
Duck typing
T   Quasi tutti i linguaggi dinamici moderni
    adottano un meccanismo di gestione degli
    attributi e delle signature degli oggetti basato
    su duck typing
               yp g
      T   Perl, PHP, Ruby, Python
T   Anche alcuni linguaggi più classici possono
    fare uso di un meccanismo di duck typing
      T   C++, tili
          C++ utilizzato con i t
                       t       template
                                    l t
      T   Template: particolare classe parametrica che
          implementa una funzionalità generica (es. lista)
          i l       t      f     i  lità     i (      li t )
      T   Il template parametrico viene istanziato in una
          classe concreta durante la compilazione
Linguaggi dinamici – A.A. 2009/2010
                                                               34
Duck typing
T   In Java, un meccanismo di duck typing è
    ottenuto tramite i generics
      T   Generics, classe parametrizzabile su un’altra
          classe
      T   public class Vettore<E> { … }
      T   …
      T   Vettore<Persona> v = new Vettore<Persona>
      T   Nell’oggetto istanziato ogni riferimento a E
          (variabili, parametri, valori di ritorno) viene
          concretizzato con la classe Persona


Linguaggi dinamici – A.A. 2009/2010
                                                            35
Programmazione polimorfa
T   Il precedente esempio (stack.cpp) è un
    classico della programmazione polimorfa
T   Alcuni problemi di programmazione si
    prestano bene ad una implementazione con le
    seguenti caratteristiche
      T   È presente una funzione “generica”
                    t       f   i    “    i ”
      T   I dettagli della funzione cambiano in base al tipo
          degli
          d li operandi di




Linguaggi dinamici – A.A. 2009/2010
                                                               36
Attenzione
T   Non bisogna confondere la tipizzazione lasca
    del C con quella dei linguaggi dinamici
T   C
     T   Quello che interessa è l’occupazione della
         memoria
     T   int i = ‘a’;
                  a;
     T   Funziona perché sizeof(char) <= sizeof(int)
T   Linguaggi dinamici
    Li      i di   i i
     T   Cercano di interpretare il significato dei valori in
         modo dinamico


Linguaggi dinamici – A.A. 2009/2010
                                                                37

T4 tipizzazione

  • 1.
    Parte 1 Tipizzazione dei dati p Linguaggi dinamici – A.A. 2009/2010 1
  • 2.
    Entità di unprogramma T In un programma, ad ogni entità è associato: T Nome, identificatore unico nel programma (o in una porzione) T Tipo, per indicare l insieme dei valori e delle l'insieme operazioni T Valore, tra quelli ammessi dal tipo T Indirizzo, riferimento alla memoria che la contiene T Tempo di vita, durata di esistenza nel programma T Visibilità (scope) del nome nel programma Linguaggi dinamici – A.A. 2009/2010 2
  • 3.
    Definizione di tipizzazione T Ciascun linguaggio di programmazione è dotato di un sistema per la tipizzazione dei dati T Tipizzazione dei dati: meccanismo trattabile di analisi sintattica che classifica una porzione del codice in base ai valori che essa calcola T Molto iù i f M lt più informalmente: il compilatore cerca l t il t di capire di che categoria (o tipo) è un valore prodotto (type checking) d tt (t h ki ) T Il tipo caratterizza le operazioni che si possono compiere sul valore prodotto, i suoi limiti, la sua “precisione” Linguaggi dinamici – A.A. 2009/2010 3
  • 4.
    Porzioni di codice T A quali porzioni di codice viene solitamente associato un tipo? T Valori in memoria (costanti) T Variabili V i bili semplici li i T Variabili complesse (strutture dati) T Espressioni T L'associazione di un tipo di dati ad una p porzione di codice informa il compilatore, l'interprete ed il programmatore su come tale p p g porzione di codice possa essere utilizzata Linguaggi dinamici – A.A. 2009/2010 4
  • 5.
    Tipi di dato T Quali sono i tipi che si possono associare alle porzioni di codice? T I tipi associabili sono classificabili in due distinte categorie T Tipi di dato semplici: caratterizzano un dato primitivo, su cui si possono effettuare i iti i i ff tt operazioni “semplici” (numero, caratteri, booleani) T Tipi di dato complessi: caratterizzano un dato composto da più dati semplici, su cui si semplici possono effettuare operazioni “complesse” (stringhe, (stringhe struttura dati, classe) dati Linguaggi dinamici – A.A. 2009/2010 5
  • 6.
    Tipi di dato T Esempi di tipi di dato semplici T Int, Integer Float double Char String Int Integer, Float, double, Char, String, Boolean T Puntatori T Esempi di tipi di dato complessi T Struct, union T Class Linguaggi dinamici – A.A. 2009/2010 6
  • 7.
    Obiettivi della tipizzazione: Safety T L'uso dei tipi permette al compilatore di scoprire il più presto possibile (a livello di compilazione) codice privo di senso/illecito T Si consideri l espressione 3 / “Hi World” l'espressione Hi World T Tale espressione (che non ha alcun senso) è scomponibile nel seguente modo: ibil l t d T Operando 1: tipo semplice intero 3 T Operando 2: tipo stringa “Hi World” T Operatore: divisione / p T L'operatore divisione non prevede le stringhe! T Il compilatore emette un syntax error Linguaggi dinamici – A.A. 2009/2010 7
  • 8.
    Obiettivi della tipizzazione: Safety T Ma attenzione! T Si consideri l'espressione ‘a’ / 5 ’ T Anche in questo caso non avrebbe senso dividere un carattere, ma il C considera questa di id tt id t espressione come ASCII(‘a’) / 5 T Si consideri l'espressione 70 / “2” T È sempre una operazione che potrebbe non avere senso, ma un compilatore/interprete potrebbe considerarla come 70 / 2 convertendo la t i l stringa “2” nell’intero che rappresenta ll’i t h t T Naturalmente se si ha una generica variabile stringa non è detto che rappresenti un numero Linguaggi dinamici – A.A. 2009/2010 8
  • 9.
    Obiettivi della tipizzazione: Ottimizzazione T Le operazioni di type checking, se eseguite in uno stadio iniziale (compilazione) possono fornire informazioni utilissime T Ad esempio, se ad una analisi sintattica segue esempio l'immediato type checking, si può scoprire che una variabile è un puntatore T Se tale indirizzo è allineato (su architetture a 32 bit un multiplo di 4 byte), l'accesso in bit, lti l b t ) l' i memoria è molto più rapido T Sapendo ciò in anticipo, il compilatore può utilizzare istruzioni efficienti per accedere al dato Linguaggi dinamici – A.A. 2009/2010 9
  • 10.
    Obiettivi della tipizzazione: Documentazione T Nei sistemi di tipizzazione più espressivi, i tipi possono servire quale utile fonte di documentazione del codice T Il tipo di dato illustra la natura di una variabile, variabile ed in ultima analisi l'intento del programmatore T Ad esempio, un timestamp (marcatore i ti t ( t temporale) è, solitamente, un intero a 32/64 bit T Dal punto di vista della comprensione del codice, è ben diverso leggere int a = 32; oppure timestamp a=32; T Definizione di nuovi tipi di dato (typedef in C) p ( yp ) per aumentare l'espressività del linguaggio Linguaggi dinamici – A.A. 2009/2010 10
  • 11.
    Obiettivi della tipizzazione: Astrazione T Il meccanismo dei tipi permette di produrre programmi ad un livello di astrazione più alto di quello nativo della macchina (bit, byte) T Ad esempio, una stringa di caratteri può esempio essere vista a basso livello come una sequenza di byte (o di bit) T Per l'essere umano, è molto più intuitivo pensare ad una stringa come ad una d ti d concatenazione di caratteri T Java: operatore + applicato alle stringhe Linguaggi dinamici – A.A. 2009/2010 11
  • 12.
    Obiettivi della tipizzazione: Modularità T L'uso appropriato dei tipi di dato costituisce uno strumento semplice e robusto per definire interfacce di programmazione (API) T Le funzionalità di una data API sono descritte dalle signature (i prototipi) delle funzioni pubbliche che la compongono T Leggendo tali signature, il programmatore (esperto) si fa immediatamente un'idea di cosa ( t ) if i di t t 'id può (o non può) fare Linguaggi dinamici – A.A. 2009/2010 12
  • 13.
    Un avvertimento T Attenzione! I meccanismi che garantiscono le proprietà ora viste non sono una panacea! T Tali proprietà aiutano a catturare errori di natura per lo più sintattica T Il meccanismo di tipizzazione (ma anche il compilatore, o l'interprete) non può nulla il t l'i t t ) ò ll contro la programmazione sloppy (sciatta) che produce errori di natura semantica d i t ti T Un ciclo non viene mai terminato T Il flusso del programma è sballato T Una risorsa acquisita non viene mai rilasciata q Linguaggi dinamici – A.A. 2009/2010 13
  • 14.
    Type checking T L'operazione di type checking ha l'obiettivo di verificare e di stabilire il tipo di dato associato ad una determinata porzione di codice T Tale operazione può avvenire: T a tempo di compilazione (compile time) T a tempo di esecuzione (run time) i ( i ) T Tale operazione può: T Garantire la non perdita di informazione durante le operazioni di conversione T Non garantire la perdita di informazione durante le operazioni di conversione p Linguaggi dinamici – A.A. 2009/2010 14
  • 15.
    Type checking statico T Un linguaggio di programmazione utilizza un meccanismo di type checking statico se le operazioni di type checking sono eseguite solo a tempo d compilazione te po di co p a o e T Linguaggi a type checking statico: T C, C++, C#, Java, Fortran, C C++ C# Java Fortran Pascal T Il type checking statico: T è inteso come una forma primitiva di verifica di un programma T permette di individuare parecchi errori con largo anticipo (early) T permette una migliore ottimizzazione del codice Linguaggi dinamici – A.A. 2009/2010 15
  • 16.
    Type checking statico T Osservazioni: T i tipi delle espressioni sono determinati durante il processo di compilazione T un compilatore non può sapere quali dati avrà il t ò li d ti à in ingresso/genererà il programma eseguibile T Il t type checking statico è conservativo h ki t ti ti T Esempio: if ('A' == 65) printf(“okn”); T L'if è vero, tuttavia il solo meccanismo di tipizzazione, senza un meccanismo di p , conversione dei tipi, non potrebbe stabilire se 'A' == 65, e dovrebbe fallire , Linguaggi dinamici – A.A. 2009/2010 16
  • 17.
    Type checking dinamico T Un linguaggio di programmazione utilizza un meccanismo di type checking dinamico se la maggior parte delle operazioni di type c ec g sono eseguite tempo d esecu o e checking so o esegu te a te po di esecuzione T Linguaggi a type checking dinamico: T Javascript, LISP, Perl, PHP, Python, Javascript LISP Perl PHP Python Ruby T Il type checking dinamico è più flessibile di quello statico ll t ti T Ad esempio, un programma può costruire strutture dati di forma mutevole a run time; pertanto, il tipo di dato cambia a run time, e va controllato a run time! Linguaggi dinamici – A.A. 2009/2010 17
  • 18.
    Type checking dinamico T Godendo di un meccanismo di tipizzazione a run time si possono effettuare gli time, assegnamenti più strani T Ad esempio: $var = <token letto da file>; T Il token può avere un qualunque tipo (intero, stringa) ti ) T Il type checker dinamico assegna il tipo corretto a run time T Provate a scrivere una cosa simile in C! Linguaggi dinamici – A.A. 2009/2010 18
  • 19.
    Type checking dinamico T Ovviamente, la flessibilità si paga T Un type checker dinamico dà minori garanzie a priori rispetto ad un type checker statico, proprio perché non può operare (solamente) a tempo di compilazione T Se, nell'esempio precedente, $ $var è intesa essere una variabile intera che va sommata ad un'altra variabile, ed a run time f fornite una stringa, l'interprete non potrà fare altro che uscire (con tanti improperi!) i ( ii i!) T Il type checker dinamico non poteva sapere dell'errore commesso in seguito dall'utente Linguaggi dinamici – A.A. 2009/2010 19
  • 20.
    Type checking dinamico T Un type checker dinamico fa alcuni controlli a tempo di compilazione T I controlli si limitano alla correttezza sintattica degli operatori T I controlli a tempo di esecuzione sono, di solito, molto più sofisticati, e coinvolgono il lit lt iù fi ti ti i l processo di identificazione di un tipo di una espressione i T I linguaggi con type checking dinamico hanno bisogno di quei controlli che il type checker statico potrebbe dare loro T Unit testing Linguaggi dinamici – A.A. 2009/2010 20
  • 21.
    Type checking staticoe dinamico T Alcuni linguaggi fanno uso di tecniche di type checking statico e dinamico T Java: T Checking statico dei tipi Ch ki t ti d i ti i T Checking dinamico (a run time) per le operazioni di d i i downcasting ( i (ossia, il casting di i i una variabile di una classe base in una delle sue sottoclassi) Linguaggi dinamici – A.A. 2009/2010 21
  • 22.
    Pro e contronella pratica T Type checking statico: T Identifica errori a tempo di compilazione (non è ben chiaro se ciò aumenta l'affidabilità del programma) T Permette la costruzione di codice che esegue più velocemente T Type checking dinamico: T Permette al compilatore di eseguire i suoi compiti molto più velocemente T Permette l'uso di costrutti considerati illegali nei linguaggi statici T Permette una più rapida prototipazione Linguaggi dinamici – A.A. 2009/2010 22
  • 23.
    Tipizzazione forte T Un linguaggio di programmazione adotta una tipizzazione forte dei dati se una operazione effettuata con operandi aventi tipo di dato non co etto e e ped ta corretto viene impedita T Un'operazione di somma di interi con caratteri T Un operazione Un'operazione in cui si superano i limiti di un array T Non esiste il linguaggio completamente tipizzato in maniera forte T Java è f t J fortemente ti i t tipizzato (più del C e del t ( iù d l d l Pascal) Linguaggi dinamici – A.A. 2009/2010 23
  • 24.
    Tipizzazione debole T Un linguaggio di programmazione adotta una tipizzazione debole dei dati se una operazione effettuata con operandi aventi tipo di dato non co etto o corretto non viene impedita e e ped ta T La tipizzazione debole fa spesso uso di operatori di conversione (casting) per rendere omogenei gli operandi T Esempio: var x:= 5; var y:= “37”; x + y; T In alcuni linguaggi (Visual Basic), y viene convertito ad intero (x+y=42) tit d i t ( + 42) T In altri linguaggi (Javascript), x viene convertito a stringa (x+y=”537”) ti ( ”537”) Linguaggi dinamici – A.A. 2009/2010 24
  • 25.
    Tipizzazione safe T Un linguaggio di programmazione adotta una tipizzazione safe (sicura) dei dati se non permette ad una operazione di casting di p odu e u produrre un risultato erroneo o un crash su tato e o eo u c as T Esempio (Visual Basic): var x:= 5; var y:= “37”; var z = x + y; 37 ; T In questo esempio, il risultato è 42 T L'operazione di conversione non f fallisce su una stringa contenente un intero T Se la stringa contenesse “Hi world”, la conversione darebbe NULL e z avrebbe un valore indefinito (senza crash) Linguaggi dinamici – A.A. 2009/2010 25
  • 26.
    Tipizzazione unsafe T Un linguaggio di programmazione adotta una tipizzazione unsafe (non sicura) dei dati se permette ad una operazione di casting di p odu e u produrre un risultato erroneo o un crash su tato e o eo u c as T Esempio (C): int x= 5; char y [] = “37”; char *z = x + y; 37 ; z T Qui, z viene posto all'indirizzo di memoria 5 byte più in avanti di y T Il contenuto di z non è definito, e può trovarsi al di fuori dello spazio di indirizzamento del l f i d ll i i di i d l processo T Una dereferenziazione di z può portare al crash Linguaggi dinamici – A.A. 2009/2010 26
  • 27.
    Tipizzazione e polimorfismo T Con il termine polimorfismo si intende la capacità (da parte di un linguaggio) di differenziare il comportamento di un metodo o d u ope ato e di un operatore in funzione dell’entità a cui è u o e de e t tà cu applicato T Alcuni linguaggi gestiscono il polimorfismo anche a livello di tipi di dato T Ad esempio in alcuni linguaggi è possibile definire esempio, una tabella associativa (tabella hash) T Le chiavi e gli elementi possono essere valori di un qualsiasi tipo (o quasi) T Non è necessario predefinire una struttura dati apposita per ogni possibile combinazione Linguaggi dinamici – A.A. 2009/2010 27
  • 28.
    Parte 1 Duck typing yp g Linguaggi dinamici – A.A. 2009/2010 28
  • 29.
    Tipizzazione classica adoggetti T Nello schema classico di un linguaggio ad oggetti, oggetti gli attributi ed i metodi a disposizione di un oggetto sono: T quelli definiti dalla classe di appartenenza dell'oggetto T quelli ereditati dalle superclassi dell oggetto dell'oggetto T (i metodi) implementati tramite interfacce T La l i L relazione fra classi va dichiarata f l i di hi esplicitamente T Parole chiavi (Java) class, extends, interface, implements Linguaggi dinamici – A.A. 2009/2010 29
  • 30.
    Tipizzazione classica adoggetti T In tale schema, individuare il tipo di un attributo e/o la signature di un metodo implica: T individuare la classe di appartenenza dell oggetto (binding) dell'oggetto (binding), con il fine di individuare un tipo per l'attributo oppure una signature valida per il metodo T In caso di mancata individuazione, ripetere il controllo per tutte le superclassi (operation dispatching – fino alla classe radice, es. Object) T In altre parole individuare un attributo e/o una parole, signature implica trovare una classe adatta (fra quelle imparentate) per l'oggetto l oggetto Linguaggi dinamici – A.A. 2009/2010 30
  • 31.
    Tipizzazione classica adoggetti T Tali controlli possono essere effettuati T A tempo di compilazione T A tempo di esecuzione T Di solito, si preferisce il tempo di compilazione (il costo a tempo di esecuzione sarebbe troppo elevato) T C++ senza l’uso di puntatori T In Java, è fatto a tempo di esecuzione Linguaggi dinamici – A.A. 2009/2010 31
  • 32.
    Duck typing T In un linguaggio di programmazione ad oggetti dinamico, dinamico basato sul meccanismo di duck typing, si rovescia tale concetto T Posso evitare di dichiarare esplicitamente la dipendenza di una classe da una superclasse T Se i t S istanzio un oggetto di tale classe ed uso i i tt t l l d suoi metodi/attributi, l'unica cosa che conta è che i metodi/attributi siano definiti h t di/ tt ib ti i d fi iti T Tecnica utilizzata per implementare il polimorfismo senza ricorrere alla ereditarietà T Attenzione: il meccanismo di ereditarietà esiste sempre! Linguaggi dinamici – A.A. 2009/2010 32
  • 33.
    Duck typing T Un type checker basato su duck typing opera tipicamente a livello di esecuzione T Se vengono referenziati un attributo o un metodo di un oggetto, si controlla solamente oggetto che il suddetto attributo o metodo siano definiti per quell oggetto (duck test) quell'oggetto T Se sono definiti, si accede al dato o si invoca la funzione T Se non sono definiti, l'interprete esce con un messaggio di errore i T Meccanismo molto più snello per il compilatore e per il programmatore Linguaggi dinamici – A.A. 2009/2010 33
  • 34.
    Duck typing T Quasi tutti i linguaggi dinamici moderni adottano un meccanismo di gestione degli attributi e delle signature degli oggetti basato su duck typing yp g T Perl, PHP, Ruby, Python T Anche alcuni linguaggi più classici possono fare uso di un meccanismo di duck typing T C++, tili C++ utilizzato con i t t template l t T Template: particolare classe parametrica che implementa una funzionalità generica (es. lista) i l t f i lità i ( li t ) T Il template parametrico viene istanziato in una classe concreta durante la compilazione Linguaggi dinamici – A.A. 2009/2010 34
  • 35.
    Duck typing T In Java, un meccanismo di duck typing è ottenuto tramite i generics T Generics, classe parametrizzabile su un’altra classe T public class Vettore<E> { … } T … T Vettore<Persona> v = new Vettore<Persona> T Nell’oggetto istanziato ogni riferimento a E (variabili, parametri, valori di ritorno) viene concretizzato con la classe Persona Linguaggi dinamici – A.A. 2009/2010 35
  • 36.
    Programmazione polimorfa T Il precedente esempio (stack.cpp) è un classico della programmazione polimorfa T Alcuni problemi di programmazione si prestano bene ad una implementazione con le seguenti caratteristiche T È presente una funzione “generica” t f i “ i ” T I dettagli della funzione cambiano in base al tipo degli d li operandi di Linguaggi dinamici – A.A. 2009/2010 36
  • 37.
    Attenzione T Non bisogna confondere la tipizzazione lasca del C con quella dei linguaggi dinamici T C T Quello che interessa è l’occupazione della memoria T int i = ‘a’; a; T Funziona perché sizeof(char) <= sizeof(int) T Linguaggi dinamici Li i di i i T Cercano di interpretare il significato dei valori in modo dinamico Linguaggi dinamici – A.A. 2009/2010 37