Linguaggi di Programmazione (20 Settembre 2011)
Esercizio 1
(a)
Definire in Haskell il tipo delle funzioni parziali da Interi ad Interi.
Definire la funzione "comp" che, prese due funzioni parziali da interi ad interi,
restituisca la loro composizione.
Definire inoltre la funzione "union" che, prese due funzioni parziali da interi a interi
f e g restituisca, con input x, f(x) se f e' definita su x, g(x) altrimenti.
(b)
Supponiamo, per semplicita', che in Pict un valore possa essere un intero,
un canale o una tupla (anche vuota) di valori. Sempre per semplicita',
supponiamo che un pattern Pict possa essere una variabile o una tupla (anche vuota)
di pattern.
Definire in Haskell:
- il tipo di dato Valore di Pict
- il tipo di dato Pattern di Pict
- l'operazione di pattern matching di Pict
Il pattern matching, se ha successo, sappiamo che restituisce un binding.
Si puo' scegliere di definire un binding come una funzione parziale (nello stile
dell'esercizio 1.a), oppure come una lista di coppie, o in qualche altro modo
che preferite. Per semplicita' si puo' supporre che il fallimento di un matching
provochi un errore, ma potete scegliere altre alternative.
Esercizio 2
(a)
Supponiamo di avere le seguenti definizioni in FJ:
class A extends Object {
A() { super(); }
}
class B extends Object {
B() { super(); }
}
La seguente espressione FJ e' correttamente tipabile?
(A)(Object)new B()
Perche?
Perche' si e' introdotta in FJ la seguente
regola di tipo?
Gamma |- e : D C non sottotipo di D D non sottotipo di C
stupid warning
----------------------------------------------------------------------
Gamma |- (C)e : C
(b)
Descrivere l'F-bounded polimorphism cosi' come utilizzato in Java. Uso, vantaggi e svantaggi.
Esercizio 3
(a)
VanRoy suggerisce, per i linguaggi O.O., di utilizzare il
meccanismo dell'Inheritance il meno possibile e di utilizzare
al suo posto il meccanismo della Composition. Perche'?
(b)
Esiste un grado di parentela tra due persone se queste
sono discendenti di una stessa persona.
Il grado di parentela di due persone e' la somma delle distanze
(nell'albero genealogico)
tra le due persone e la prima di cui sono entrambe discendenti.
Scrivere un programma Prolog che calcoli, se esiste, il grado di parentela
di due persone (supponendo di avere una base di dati di fatti del tipo
"parent(tizio,caio)." che indicano che tizio e' figlio di caio).