Linguaggi di Programmazione (5 Luglio 2013)

Esercizio 1
Scrivere un programma Haskell che riconosca o rifiuti stringhe appartenenti al linguaggio regolare, sull'alfabeto {a,b,c}, associato alla seguente espressione regolare
abc*b + aa
Ricordiamo che il tipo String in Hakell coincide con [Char] e che un carattere si rappresenta tra apici (es.: 'a').
Esercizio 2
Descrivere il Principal Pair Algorithm fornendone una succinta giustificazione.
Esercizio 3
Quello che segue e' uno schema di codice Ocaml-like in cui un metodo m viene "overridden" nella sottoclasse, modificando da S ad S' il tipo del suo argomento.
class aClass2 =
   object 
       ...
   method m(s:S) = ...    
       ...
   end


class aSubclass2 =
   object 
   inherits aClass2 as super 
   ...
   method m(s:S’) = ...    
   ...
   end
Aggiungere del codice allo schema, una volta per mostrare che S' deve necessariamente essere un sottotipo di S; ed una seconda volta per mostrare che S deve essere un sottotipo di S'. A quale conseguenza portano i due esempi?
Esercizio 4
Nei testi e' riportata una frase di K.Bruce in cui si afferma che tra i principali vantaggi dei linguaggi statically typed c'e' quello che i tipi forniscono "extra information that can be used in compiler optimizations". Motivare la validita' di questa affermazione utilizzando PICT come esempio.
Esercizio 5
Discutere brevemente del concetto di chiusura (closure).
Esercizio 6
Il seguente modulo Erlang permette di calcolare una funzione map che restituisce lo stesso valore della funzione Haskell
map f [] = []

map f (x:xs) = (f x):(map f xs)
ma in modo tale che ogni valore della lista di output viene calcolato da un processo (Actor) differente
-module(mapfun).
-export([map/2,compute/3]).


collectRes([]) -> [];

collectRes([ID|IDs]) -> receive
                           {ID,Res} -> [Res|collectRes(IDs)]
                        end.


map(_,[]) -> [];

map(F,List) ->

         ComputingActors = [spawn(mapfun,compute,[F,X,self()]) || X <- List ], 
         
         collectRes(ComputingActors).                             



compute(F,X,Collector) -> Res = F(X),
                          Collector!{self(),Res}.
Ricopiare e commentare il codice descrivendo sinteticamente il suo funzionamento.