2010.11.19 iniziare con F#

1,807 views

Published on

In Visual Studio 2010 è apparso un nuovo linguaggio: F#. Cos'è, da dove nasce, come si scrive in F#. E perchè tanti lo stanno apprezzando più di C#...

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,807
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

2010.11.19 iniziare con F#

  1. 1. In collaborazione con Iniziare con F# » Marco Parenzan
  2. 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. 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. 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. 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. 6. Trends [Source: PDC 2010 – Anders Heijsberg] Declarative ConcurrentDynamic
  7. 7. 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
  8. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 21. In collaborazione con Elementi di F# 19/11/2010 www.xedotnet.org 21
  22. 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. 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. 24. 19/11/2010 www.xedotnet.org 24 » Immutability • Side-effects » Composition / Currying » Pattern Matching » Type inference » Recursion » Workflows Concetti Chiave
  25. 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. 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. 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. 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. 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. 30. 19/11/2010 www.xedotnet.org 30 » Reflector supportà già F# (con un suo plug- in, non ancora completo) F# e Reflector
  31. 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. 32. 19/11/2010 www.xedotnet.org 32 » let restituisce sempre il pattern della definizione del valore Pattern
  33. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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>
  43. 43. NASA Mars Climate Orbiter, 1999 [Source: PDC 2010 – Andrew Kennedy]
  44. 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. 45. Iniziare con F#
  46. 46. In collaborazione con Iniziare con F# Conclusioni 17/01/2008 www.xedotnet.org 46
  47. 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. 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. 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. 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

×