In collaborazione con
Iniziare con F#
» Marco Parenzan
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
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
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
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
Trends [Source: PDC 2010 – Anders Heijsberg]
Declarative
ConcurrentDynamic
C# and VB Evolution [Source: PDC 2010 – Anders Heijsberg]
Managed Code
Generics
Language
Integrated Query
Dynamic + Language
Parity
C# + VB v.Next
Asynchronous
Programming
C# 1.0 + VB 7.0
C# 2.0 + VB 8.0
C# 3.0 + VB 9.0
C# 4.0 + VB 10.0
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
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
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
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
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
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
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#
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
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
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#
» 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/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
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
In collaborazione con
Elementi di F#
19/11/2010 www.xedotnet.org 21
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
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|]
19/11/2010 www.xedotnet.org 24
» Immutability
• Side-effects
» Composition / Currying
» Pattern Matching
» Type inference
» Recursion
» Workflows
Concetti Chiave
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'
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
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
>
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
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
19/11/2010 www.xedotnet.org 30
» Reflector supportà già
F# (con un suo plug-
in, non ancora
completo)
F# e Reflector
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
19/11/2010 www.xedotnet.org 32
» let restituisce
sempre il pattern
della definizione del
valore
Pattern
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
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"
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"
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
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
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
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
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
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
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>
NASA Mars Climate Orbiter, 1999 [Source: PDC 2010 – Andrew Kennedy]
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
Iniziare con F#
In collaborazione con
Iniziare con F#
Conclusioni
17/01/2008 www.xedotnet.org 46
Perchè apprendere l’approccio funzionale
» Maggiore controllo del codice
• Minimizzare lo stato (mutable)
• Organizzare il codice
• Applicazione di Pattern
• Esalta l’immutabilità dei dati
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
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
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

2010.11.19 iniziare con f#

  • 1.
    In collaborazione con Iniziarecon F# » Marco Parenzan
  • 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
  • 6.
    Trends [Source: PDC2010 – Anders Heijsberg] Declarative ConcurrentDynamic
  • 7.
    C# and VBEvolution [Source: PDC 2010 – Anders Heijsberg] Managed Code Generics Language Integrated Query Dynamic + Language Parity C# + VB v.Next Asynchronous Programming C# 1.0 + VB 7.0 C# 2.0 + VB 8.0 C# 3.0 + VB 9.0 C# 4.0 + VB 10.0
  • 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 perlo 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
  • 21.
    In collaborazione con Elementidi F# 19/11/2010 www.xedotnet.org 21
  • 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|]
  • 24.
    19/11/2010 www.xedotnet.org 24 »Immutability • Side-effects » Composition / Currying » Pattern Matching » Type inference » Recursion » Workflows Concetti Chiave
  • 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
  • 30.
    19/11/2010 www.xedotnet.org 30 »Reflector supportà già F# (con un suo plug- in, non ancora completo) F# e Reflector
  • 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
  • 32.
    19/11/2010 www.xedotnet.org 32 »let restituisce sempre il pattern della definizione del valore Pattern
  • 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 typeExpr = | 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 letbind 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>
  • 43.
    NASA Mars ClimateOrbiter, 1999 [Source: PDC 2010 – Andrew Kennedy]
  • 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
  • 45.
  • 46.
    In collaborazione con Iniziarecon F# Conclusioni 17/01/2008 www.xedotnet.org 46
  • 47.
    Perchè apprendere l’approcciofunzionale » Maggiore controllo del codice • Minimizzare lo stato (mutable) • Organizzare il codice • Applicazione di Pattern • Esalta l’immutabilità dei dati
  • 48.
    Vale la penaimparare 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 2010www.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