2. 19/11/2010 www.xedotnet.org 2
» Non è possibile insegnare a programmare in F#
in un’ora
» Si vuole rispondere a due domande:
• Perchè apprendere l’approccio funzionale?
• Vale la pena imparare F#?
Obiettivi
3. 19/11/2010 www.xedotnet.org 3
» Da Wikipedia
http://en.wikipedia.org/wiki/Imperative_programming
• «...la computazione viene espressa in termini di
istruzioni che cambiano lo stato di un programma...»
» Nella programmazione imperativa, noi...
• ...NON diciamo COSA vogliamo....
• ...ma DICIAMO COME fare per ottenere quello che
vogliamo
Programmazione Imperativa
4. 19/11/2010 www.xedotnet.org 4
» Nella programmazione imperativa, i concetti principali sono:
• Lo stato (le variabili)
• L’assegnazione (delle variabili)
• La sequenza delle operazioni (che cambiano lo stato delle variabili)
» Pros
• Approccio «naturale»
• «The hardware implementation of almost all computers is imperative »
• Ad un certo punto l’esecuzione va fatta
• Quando viene insegnato il concetto astratto di algoritmo, viene
implicitamente richiesto di essere gli «esecutori»
» Cons
• La gestione dello stato può essere complicata ed è spesso causa di
errori
• Forse abusiamo delle variabili
• Sempre di più ora che si parla di parallel e distributed programming
Programmazione Imperativa
5. 19/11/2010 www.xedotnet.org 5
» Da Wikipedia
http://en.wikipedia.org/wiki/Object-oriented_programming
• «...i dati vengono espressi in termini di strutture
contenenti campi e metodi...»
» La programmazione orientata agli oggetti è
implicitamente imperativa, in quanto è «stato»
assieme ai metodi che permetto di «cambiare
questo stato»
» Nel nostro ragionamento, quindi, non ci interessa
• I concetti di OOP non ci danno niente in più nel
confronto Imperativo vs. Funzionale
• Comunque parleremo di F# e OOP
Programmazione Orientata agli Oggetti
8. 19/11/2010 www.xedotnet.org 8
» C# 3.0 (rilasciato con .NET Framework 3.5) implementa alcuni aspetti della
programmazione funzionale (http://tomasp.net/articles/csharp3-concepts.aspx)
• Lambda Expression
• Quando le funzioni possono essere create a runtime, possono essere memorizzate in
strutture dati, essere passate come parametri o ritornate come risultati
• Type Inference (Inferenza di tipo)
• Dedurre il tipo dall’espressione, non dalla annotazione della variabile (che, in caso di
ambiguità, si può ancora usare)
• Anonymous Types
• Tipi definiti dall’uso
• Metaprogramming
• È lo scrivere programmi che scrivono o manipolano altri programmi (se scrivono o
manipolano se stessi, si dice «reflection»)
• Le Expressions e gli Expression Trees sono i fondamenti del metaprogramming in .NET
3.5/sp1/4.0 (oltre alla Reflection...)
• In realtà sono: syntactic sugar e librerie
• Cosa succede se questi concetti entrano nella definizione del linguaggio sin
dall’inizio?
Programmazione Funzionale e .NET
9. 19/11/2010 www.xedotnet.org 9
» Da Wikipedia
http://en.wikipedia.org/wiki/Declarative_programming
• «...esprime la logica della computazione SENZA
descrivere il flusso di controllo...»
» Nella programmazione dichiarativa, noi...
• ...DICIAMO COSA vogliamo....
• ...ma NON diciamo come fare per ottenere quello
che vogliamo
» È l’esatto complemento della programmazione
dichiarativa
Programmazione Dichiarativa
10. 19/11/2010 www.xedotnet.org 10
» Nella programmazione dichiarativa, i concetti
principali sono:
• Le proprietà (esplicitare dei valori)
• I vincoli (esplicitare le regole cui devono sottostare valori
non esplicitati)
» Pros
• Migliore astrazione
• Non devo pensare alla gestione dello stato
» Cons
• Approccio (forse) non «naturale» (?!?!?!)
• Lo usiamo, ma non sappiamo che lo stiamo facendo
Programmazione Dichiarativa
11. 19/11/2010 www.xedotnet.org 11
» Tra i linguaggi «dichiarativi» (cioè quelli che
implementano un paradigma di programmazione
«dichiarativo») troviamo i Domain Specific
Languages
» Ne usiamo ogni giorno
• HTML
• Descriviamo cosa vogliamo vedere
• Non descriviamo COME faremo a rappresentarlo (non
disegnamo linee, lettere, colori)
• SQL
• Nella selezione (SELECT) descriviamo i vincoli sui dati che
vogliamo ottenere,
• Non descriviamo COME estrarre i dati da un database
(generazione dell’execution plan)
Domain Specific Languages
12. 19/11/2010 www.xedotnet.org 12
» Da Wikipedia
http://en.wikipedia.org/wiki/Functional_programming
• «...la computazione viene espressa in termini di funzioni ed evita l’uso di stato e dati mutabili...»
» Nella programmazione funzionale...
• Le funzioni sono First-Class Types (High Order Functions)
• Inferenza dei tipi
• Immutabilità
• La scelta di essere «mutabile» (ed essere a rischio di «side effectes», è esplicita)
• Evita l’uso di stato per evitare insidiosi «side-effects»
• Specie in concurrent programming
• Enfatizza la forma dei dati, non l’implementazione
• Uso di dati polimorfici e di pattern matching
• Modellato sul lambda calcolo
• Expression Oriented
• Promuove la «lazy evaluation»
• Valutazione «pigra», il più tardi possibile (non «eager», «impaziente», «anticipato»)
• Riduce l’enfasi sull’approccio imperativo
• Preferisce la ricorsione all’iterazione
• Innalza il livello di astrazione
Programmazione Funzionale
13. 19/11/2010 www.xedotnet.org 13
» Nella programmazione funzionale, i concetti
principali sono:
• I valori e la loro immutabilità
• Non ci sono variabili
• Il lambda calcolo
» Pros
• Migliore astrazione
• «... l'aumento delle prestazioni dei calcolatori ha tuttavia
spostato l'attenzione della comunità informatica sullo sviluppo
rapido del software, sulla sua correttezza e manutenibilità...»
» Cons
• Approccio (forse) non «naturale» (?!?!?!)
• Lo usiamo, ma non sappiamo che lo stiamo facendo
Programmazione Funzionale
14. 19/11/2010 www.xedotnet.org 14
» È un linguaggio funzionale
• Deriva la sua sintassi dal linguaggio Ocaml
• È il suo obiettivo principale
» È un linguaggio imperativo
• Se non si può fare altrimenti
» È un linguaggio OOP
• Perchè deve essere interoperabile con .NET
» Links
• http://msdn.microsoft.com/en-us/fsharp/default.aspx
• http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/
• http://en.wikipedia.org/wiki/F_Sharp_(programming_language)
Cos’è F#
15. F# Evolution [Source: PDC 2010 – Don Syme]
F# 1.0
Functional, Generics (Microsoft
Research)
…
Visual Studio 2008
Interactive, Objects
F# 2.0
Visual Studio 2010
Asynchronous, Parallel, Units of
Measure
Language foundations for strongly typed
access to external named data and
services
F# 3.0
16. 19/11/2010 www.xedotnet.org 16
» Iniziato nel 2002 in Microsoft Research ad opera
principalmente di Don Syme
• http://blogs.msdn.com/b/dsyme/
• http://en.wikipedia.org/wiki/Don_Syme
» A Don si deve anche l’implementazione dei generics nel
CLR 2.0 (usati poi pesantemente in F#)
» A inizio 2005 viene rilasciata la prima release pubblica di F#
• http://blogs.msdn.com/b/dsyme/archive/2005/01/05/346857.aspx
» Nel 2009 Somasegar annuncia l’inclusione di F# (2.0) in Visual Studio 2010
• http://blogs.msdn.com/b/somasegar/archive/2009/10/09/f-in-vs2010.aspx
» Il 4 novembre 2010 il source code di F# viene rilasciato come Open Source
• http://blogs.msdn.com/b/dsyme/archive/2010/11/04/announcing-the-f-
compiler-library-source-code-drop.aspx
» Si può anche installare sotto Linux e Mac OSX con MONO
• http://fsxplat.codeplex.com/
Storia
17. 19/11/2010 www.xedotnet.org 17
» ...fermo restando che F# è un General Purpose
Language
• Implementa anche l’approccio imperativo
» Alcuni domini importanti
• Financial Modeling
• Data Mining
• Scientific Analisys
• Academic
Applicazioni tipiche per F#
18. » Shell per lo scripting interattivo
• Ottimo per la prototipazione
» Conciso
» Type Inference
• Strongly Typed
• Automatic Generalization (sempre generico, se ha senso)
• Poca Type Annotation (attributi)
» First Class Functions
• Currying, Lazy Evaluations
» Pattern matching
Caratteristiche di F#
19. 19/11/2010 www.xedotnet.org 19
» Utilizzato in ambito amministrativo, matematico o
Dynamic Languages
• Cmd, PowerShell, Mathematica, (Iron)Python, (Iron)Ruby
» L’utente inserisce i comandi uno alla volta,
eseguendoli
• Normalmente, i linguaggi di scripting sono interpretati
• F# è compilato
» Uno scripting è di successo quanto più semplice è
scrivere il codice
• In F# è possibile avere la verifica (statica) dei tipi
Scripting Interattivo
20. 19/11/2010 www.xedotnet.org 20
» Da riga di comando, digitare
fsi.exe
» Da Visual Studio 2010, due
opzioni
• CTRL+ALT+F per una console F#
interactive
• Creare un progetto F#, inserire un
file .fsx ed eseguire «selezioni» di
codice con ALT+INVIO
L’ambiente interattivo
22. 19/11/2010 www.xedotnet.org 22
» Shell interattiva
» In una shell
interattiva, i comandi
vengono terminati
con il doppio
carattere ;;
» it è l’ultimo valore
calcolato
» It non è it
• F# è Case Sensitive
Shell Interattiva
> 3+4
> 3+4;;
val it : int = 7
>it
val it : int = 7
>It
Script.fsx(3,1): error FS0039: The value
or constructor 'It' is not defined
23. 19/11/2010 www.xedotnet.org 23
» Liste
» Tuple
» Record
» Array
Tipi di dati
>let lista = [1..10];;
val lista : int list = [1; 2; 3; 4; 5; 6; 7; 8;
9; 10]
>let tupla = (1, "due", 3.0, false);;
val tupla : int * string * float * bool = (1,
"due", 3.0, false)
>let a,b,c,d = tupla;;
val d : bool = false
val c : float = 3.0
val b : string = "due"
val a : int = 1
>type Person = { Name: string; Surname: string; };;
type Person =
{Name: string;
Surname: string;}
>let p = { Name="Mario"; Surname="Rossi" };;
val p : Person = {Name = "Mario";
Surname = "Rossi";}
>let values = [|10; 20; 30|
val values : int [] = [|10; 20; 30|]
25. 19/11/2010 www.xedotnet.org 25
» let permette di
definire valori
• F# applica sempre la
Type Inference (a :
int)
• Simile a var in C#...
• ...ma il feeling è quello
dello scripting...
» a è un valore, non
una variabile
• a è immutabile
Valori, non variabili
> let a = 4;;
val a : int = 4
> let a = 5;;
Script.fsx(5,5): error FS0037: Duplicate
definition of value 'a'
26. 19/11/2010 www.xedotnet.org 26
» let mutable
permette di definire
valori mutabili
» a diventa
sostanzialmente una
variabile
» Motto:
• «se proprio serve...»
Valori «mutabili», allora variabili
> let mutable a = 4;;
val a : int = 4
> let a = a + 1;;
val a : int = 5
27. 19/11/2010 www.xedotnet.org 27
» let permette di
definire funzioni
• Le funzioni sono valori
• Le funzioni associano
ad valori in ingresso
dei valori in uscita
» Le funzioni sono
valori
Funzioni come valori
> let f x = x + 1;;
val f : int -> int
> f 5;;
val it : int = 6
>
28. 19/11/2010 www.xedotnet.org 28
» f x si può anche
scrivere come x |> f
» In caso di due
parametri, il parametro
in pipelining è quello
più a destra
• y |> f x
• È ottimo quando si
usano applicazioni in
sequenza
Pipelining operator
> let incr x = x + 1
val incr : int -> int
> 10 |> incr
val it : int = 11
> let f x y = x*2+y*3
val f : int -> int -> int
> 10 |> f 20
val it : int = 70
>let values = [1..10]
let sumOfValues = values |> List.filter (fun x -> (x % 2 = 0))
|> List.map (fun x -> x*2)
|> List.fold (+) 0
val values : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
val sumOfValues : int = 60
29. 19/11/2010 www.xedotnet.org 29
» È possibile valorizzare
parzialmente i parametri di una
funzione componendo un
nuovo valore (partial function
application)
» Infatti notiamo che dopo una
let viene sempre mostrato il
formato del valore
» Il meccanismo si chiama
«currying»
http://en.wikipedia.org/wiki/Cu
rrying
• È una tecnica che permette di
trasformare una funzione di n
parametri in una «catena di
funzioni di un solo parametro»
Composition
>let f x y = x + y
>let incr x = f x 1
>incr 5
val f : int -> int -> int
val incr : int -> int
val it : int = 6
31. 19/11/2010 www.xedotnet.org 31
» Cosa genera questo
programma in F#? (che
non significa niente...)
let a = 4
let mutable b = a + 5
let f x = x + a
let g = f b
» Se si usa Reflector...
F# e Immutability dal punto di vista di .NET
33. 19/11/2010 www.xedotnet.org 33
» Anche chiamate
«option types»
» Simile all’ereditarietà
in OOP
• «functional
inheritance»
» Anche il tipo diventa
un valore
• Simile a una Enum???
Discriminated Unions
>type Veicolo =
| Auto
| Moto
| Camion
;;
>let veicolo = Auto;;
val veicolo : Veicolo = Auto
34. 19/11/2010 www.xedotnet.org 34
» È possibile adornare
l’alternativa del tipo
con degli attributi
Discriminated Union
>type Nome = string
>type Marca= string
>type Colore = string
>type Veicolo =
| Auto of Colore
| Moto of Marca
| Camion of Nome
>let veicolo = Auto("rossa")
val veicolo : Veicolo = Auto "rossa"
35. 19/11/2010 www.xedotnet.org 35
» La «sequenza» di
informazioni di tipo e di
attributi può essere
usata per
«discriminare» il tipo
» La sequenza di tipo e di
attributi è un «pattern»
» È uno dei meccanismi
fondamentali di F#
• http://en.wikibooks.org/wiki/F_Sh
arp_Programming/Pattern_Matchi
ng_Basics
Pattern Matching
type Nome = string
type Marca= string
type Colore = string
type Veicolo =
| Auto of Colore
| Moto of Marca
| Camion of Nome
let veicolo = Auto("rossa")
match veicolo with
| Auto(colore) -> printfn "Un' auto %s" colore
| Moto(marca) -> printfn "Una moto %s" marca
| _ -> printfn "un veicolo qualsiasi"
36. 19/11/2010 www.xedotnet.org 36
type Expr =
| Num of int
| Add of Expr * Expr
| Mul of Expr * Expr
| Var of string
let rec Evaluate (env:Map<string,int>) exp =
match exp with
| Num n -> n
| Add (x,y) -> Evaluate env x + Evaluate env y
| Mul (x,y) -> Evaluate env x * Evaluate env y
| Var id -> env.[id]
let envA = Map.ofList [ "a",1 ;
"b",2 ;
"c",3 ]
let expT1 = Add(Var "a",Mul(Num 2,Var "b"))
let resT1 = Evaluate envA expT1
Un esempio evoluto di pattern matching
type Expr =
| Num of int
| Add of Expr * Expr
| Mul of Expr * Expr
| Var of string
val Evaluate : Map<string,int> -> Expr -> int
val envA : Map<string,int> = map [("a", 1); ("b", 2);
("c", 3)]
val expT1 : Expr = Add (Var "a",Mul (Num 2,Var "b"))
val resT1 : int = 5
37. 19/11/2010 www.xedotnet.org 37
» Osservare cosa F# ha generato a
fronte del codice scritto prima,
descrive molto bene il concetto
di «declarative programming»
detto all’inizio
» Classi già implementate (e
spesso lo si faceva a mano)
» Uso estensivo di:
• IEquatable
• IStructuralEquatable
• IComparable
» Sono i concetti trovati negli
«anonymous types» in C# 3.0
» In C# lo si poteva fare, ma non
siamo mai stati realmente
abituati a farlo
Discriminated Union, Pattern Matching e Reflector
38. 19/11/2010 www.xedotnet.org 38
» Una funziona viene
dichiarata ricorsiva con
la parola chiave rec
» È l’equivalente
funzionale
dell’iterazione
» Si ha spesso paura di
usare le funzioni
ricorsive per le
prestazioni e il
«consumo» dello stack
Ricorsione
> let rec factorial = function
| 0 | 1 -> 1
| n -> n * factorial (n - 1)
> factorial 10
val it : int = 3628800
39. 19/11/2010 www.xedotnet.org 39
» Tail Call Optimization è una caratteristica del
compilatore F# (e in alcuni casi anche del JITer .NET)
che trasforma una funzione ricorsiva in un ciclo
while se la chiamata ricorsiva è l’ultima.
» Questa ottimizzazione risolve il problema dello
stack overflow
» Bisogna sempre tentare di pensare ad una funzione
affinchè sia “tail optimizable”
• Perchè il compilatore (o il JITer) non fanno tutto da solo
» Il TCO è disponibile nel CLR 4.0
• Quindi anche in C#!
Tail Recursion
40. 19/11/2010 www.xedotnet.org 40
» Il codice che è
applicabile a più tipi,
viene
automaticament
generalizzato
» È interessante notare
come il codice
generato dipenda
fortemente da
funzioni standard di
libreria
Automatic Generalization
>let max a b = if a>b then a else b
val max : 'a -> 'a -> 'a when 'a :
comparison
41. 19/11/2010 www.xedotnet.org 41
» Sono un concetto complicato
» Permette di definire un DSL
• F# mette a disposizione delle parole chiave, integrate nel linguaggio (let,
let!, use, use!, do, do!, for, while if, yield, yield!, return, return!)
• «Mappa» queste parole chiave sui metodi di una classe «builder» (Let,
Bind, Using, For, While, if, Combine, Yield, YieldFrom, Return, ReturnFrom)
• Questi metodi possono essere implementati da un programma
• Quindi un «workflow» scritto con quelle parole chiave viene eseguito
come sequenza di metodi dell’oggetto builder, di cui noi abbiamo
pienamente il controllo
» È un approccio AOP (Aspect Oriented Programming)
http://en.wikipedia.org/wiki/Aspect-oriented_programming
• I metodi (Let, Bind, ....) «osservano» l’esecuzione del programma e
agiscono in background
• Ad esempio per un logging...
Computational Workflow
42. 19/11/2010 www.xedotnet.org 42
let bind value1 function1 =
printfn "Bind %A." value1
function1 value1
let result value1 =
printfn "Returning result: %A" value1
fun () -> value1
let delay function1 =
fun () -> function1()
type TraceBuilder() =
member x.Bind(value1, function1) =
bind value1 function1
member x.Return(value1) = result value1
member x.Delay(function1) =
printfn "Starting traced execution."
delay function1
let trace = new TraceBuilder()
let trace1 = trace {
let! x = 7
let! y = 5
let! sum = x + y
return sum
}
trace1()
Tracing Workflow
>val bind : 'a -> ('a -> 'b) -> 'b
val result : 'a -> (unit -> 'a)
val delay : (unit -> 'a) -> unit -> 'a
type TraceBuilder =
class
new : unit -> TraceBuilder
member Bind : value1:'c * function1:('c -> 'd) -> 'd
member Delay : function1:(unit -> 'a) -> (unit -> 'a)
member Return : value1:'b -> (unit -> 'b)
end
val trace : TraceBuilder
Starting traced execution.
val trace1 : (unit -> unit -> int)
Bind 7.
Bind 5.
Bind 12.
Returning result: 12
val it : (unit -> int) = <fun:result@40>
44. 19/11/2010 www.xedotnet.org 44
» È un estensione al Type
system extension
» Non è invasivo
• È un meccanismo di
annotazione basato sul
processo di inferenza
» Non ha costo a runtime
» Attenzione!
• È una prima versione
• Ci sono diverse cose da
fare
• Ma è già un gran bel
lavoro
Unità di Misura
>[<Measure>]
type m;;
[<Measure>]
type m
>[<Measure>]
type s;;
[<Measure>]
type s
>let space = 10.0<m>;;
val space : float<m> = 10.0
>let time = 2.0<s>;;
val time : float<s> = 2.0
>let speed = space/time;;
val speed : float<m/s> = 5.0
>let acc = space/time/time;;
val acc : float<m/s ^ 2> = 2.5
47. Perchè apprendere l’approccio funzionale
» Maggiore controllo del codice
• Minimizzare lo stato (mutable)
• Organizzare il codice
• Applicazione di Pattern
• Esalta l’immutabilità dei dati
48. Vale la pena imparare F#?
» Tutto ciò che si può fare in C# lo si può fare in F# (almeno, al momento, mi
pare…)
• È multiparadigma (supporta l’approccio imperativo)
• Esalta l’immutabilità dei dati e la valutazione di espressioni (sembra tutto LINQ!)
• È interoperabile con .NET
» Alcune cose sono più semplici
• Applicare i design patterns
• Sintassi più succinta
• Task asincroni (workflow)
• Operazioni di trasformazione
• Computazioni
• Domain Specific Languages
• Aspect Oriented Programming
» Alcune cose sono più complicate
• GUI programming
» C’è già un sacco di codice F# in Internet da riusare
49. Libri & Blog
» Beginning F#
• Robert Pickering - APress
• http://www.amazon.com/Beginning-F-Robert-
Pickering/dp/1430223898/ref=sr_1_1?ie=UTF8&s=books&qid=1290127128&sr=8-1-spell
• Blog: http://strangelights.com/blog/
» Expert F# 2.0
• Don Syme, Adam Granicz, Antonio Cisternino - APress
• http://www.amazon.com/Expert-2-0-Experts-Voice-Syme/dp/1430224312/ref=pd_sim_b_3
• Blog: http://blogs.msdn.com/b/dsyme/
» Programming F#
• Chris Smith - O’Reilly
• http://www.amazon.com/Programming-comprehensive-writing-complex-
problems/dp/0596153643/ref=pd_bxgy_b_img_b
• Blog: http://blogs.msdn.com/b/chrsmith/
» Real World Functional Programming: With Examples in F# and C#
• Tomas Petricek – Manning
• http://www.amazon.com/Real-World-Functional-Programming-
Examples/dp/1933988924/ref=pd_bxgy_b_img_b
• Blog: http://tomasp.net/
» Professional F#
• Ted Neward, Aaron Erickson, Talbott Crowll, Rick Minerich – Wrox
• http://www.amazon.com/Professional-F-2-0-Ted-
Neward/dp/047052801X/ref=sr_1_1?ie=UTF8&s=books&qid=1290127457&sr=1-1
• Blog: http://blogs.tedneward.com/
19/11/2010 www.xedotnet.org 49
50. blog:
email:
web:
twitter:
slideshare:
Link
21 maggio 2010 www.xedotnet.org 50
» Marco Parenzan
http://blog.codeisvalue.com/
marco.parenzan@libero.it
http://www.codeisvalue.com/
marco_parenzan
http://www.slideshare.com/marco.parenzan