Presentation is loading. Please wait.

Presentation is loading. Please wait.

F# Introduction to F# Making Programming Functional Adam Granicz IntelliFactory, EPAM Systems.

Similar presentations


Presentation on theme: "F# Introduction to F# Making Programming Functional Adam Granicz IntelliFactory, EPAM Systems."— Presentation transcript:

1 F# Introduction to F# Making Programming Functional Adam Granicz granicz.adam@intellifactory.com IntelliFactory, EPAM Systems

2 Agenda Motivation for functional programming (FP) Functional programming concepts F# - constructs Functional, Language-oriented F# Interactive

3 Motivation - What we would like Programmers make mistakes  so we need More effective abstractions to express what we need in fewer lines of code Better type system to guard from misuse These can give us Abstractions/Type System  Few or no conceptual errors Fewer LoC  Fewer bugs, better maintainability

4 Motivation - and we really wish for… Program Synthesis Generate programs based on a specification  A shift towards declarative programming  Eliminate programming errors for good Program Correctness Verify that a program fulfills its specification  Theorem provers, model checkers, etc.

5 Functional concepts Higher-order functions Functions that take function parameters and/or return functions as result  Functions are first-class values  Anonymous functions Immutability Values are NOT mutable Currying Partial function application yields a function

6 Functional concepts (Parametric) Polymorphism ADTs are truly polymorphic: Map Type inference No need to type annotate programs, types are automatically inferred from use

7 Functional concepts Lazy vs. eager evaluation Values are evaluated when needed versus when they are encountered Recursion Problem solving is done by recursively breaking down a larger problem into small ones Mutually Recursive and Recursive types Recursive values  Delayed evaluation

8 F# Functional, object-oriented Strongly-typed (type-safe), type inferred, garbage collected Succint, expressive, composable Interoperable with any.NET language.NET runtime support, tools, libraries http://research.microsoft.com/fsharp/fsharp.aspx

9 F# code sample … Edit text and revise your documents

10 F# constructs 1 Functional 1.1 Concise syntax 1.2 Data abstractions discriminated unions, pattern matching polymorphic abstract data structures type augmentation 1.3 Control abstractions Computation expressions (sequences, workflows) 2 Imperative (loops, mutable cells, exceptions, IO) 3 Object-oriented (classes, interfaces) 4 Language-oriented Active patterns, reflection, quotations, AST representations

11 1.1 F# syntax Traditional vs. #light syntax Indentation matters, fewer keywords, more readable code let f a b =let f a b = let c,d = a+b, a–b inlet c,d = a+b, a-bc*d Piping functions Encourages a more functional style, helps in type inference let (|>) x f = f x let (>>) f g x = g (f x)

12 1.2 Abstractions – Data types Discriminated unions type exp = | Number of int | Add of exp * exp | Subtract of exp * exp | Multiply of exp * exp | Divide of exp * exp

13 1.2 Abstractions – Data types Pattern matching let rec eval = function | Number i -> i | Add (e1, e2) -> eval e1 + eval e2 | Subtract (e1, e2) -> eval e1 - eval e2 | Multiply (e1, e2) -> eval e1 * eval e2 | Divide (e1, e2) -> eval e1 / eval e2

14 1.2 Abstractions – Data types Polymorphic abstract data structures List, Array, Seq Map, Set, etc… type ‘a tree = | Node of ‘a * ‘a tree * ‘a tree | Leaf

15 1.2 Abstractions – Data types Tuples Pairs of values (1, 2) ((1, 2), (1, 2)) ([1; 2; 3], 4) Also, n-tuples (1, 2.0, “3”, 4I,..) Also, options, records, lists, arrays, sequences, etc.

16 1.2 Abstractions – Type augmentation Enriching a complex type type trig = | Number of double | Sin of trig | Cos of trig | Add of trig * trig | Mul of trig * trig | Inv of trig with static member Tan t = Mul (Sin t, Inv (Cos t)) static member Cot t = Mul (Cos t, Inv (Sin t)) static member (/) (t1, t2) = Mul (t1, Inv t2) end

17 1.2 Abstractions – Type augmentation Augmenting existing types module NumberTheoryExtensions = let isPrime(i) = let lim = int(sqrt(float(i))) let rec check j = j > lim or (i % j <> 0 && check (j+1)) check 2 type System.Int32 with member i.IsPrime = isPrime(i) Edit text and revise your documents

18 1.2 Abstractions – Type augmentation Augmenting existing types > open NumberTheoryExtensions;; > (3).IsPrime;; val it : bool = true > (6093711).IsPrime;; val it : bool = false Edit text and revise your documents

19 1.3 Computation expressions / Workflows Sequence expressions building, generating, and operating on sequences, lists, and arrays Asynchronous workflows Probabilistic workflows Other workflows workflow builders + syntax desugaring Quoted workflows  quotations (language-oriented)

20 1.3.1 Sequence expressions - building Building sequences using range expressions > seq {0.. 2};; val it : seq = seq [ 0; 1; 2; ] > seq {-100.0.. 100.0};; val it : seq = seq [ -100.0; -99.0; -98.0;... ] > seq {1I.. 1000000000000I};; val it : seq = seq [ 0I; 1I; 2I; 3I;... ] Using a skip value > seq { 0.. 2.. 5 };; val it : seq = seq [ 0; 2; 4 ]

21 1.3.1 Sequence expressions - iterating > let range = seq {0.. 2.. 6};; val range : seq > for i in range do printfn "i = %d" i;; i = 0 i = 2 i = 4 i = 6

22 1.3.1 Sequence expressions – aggregation open System.IO let rec allFiles dir = Seq.append (dir |> Directory.GetFiles) (dir |> Directory.GetDirectories |> Seq.map allFiles |> Seq.concat) > let files = allFiles @"c:\projects";; val files : seq > files;; val it : seq = seq ["c:\\projects\\AmazonSalesRank\\AmazonSalesRank.sln";...

23 1.3.1 Sequence comprehensions let squares = seq { for i in 1.. 100 -> (i, i*i) } let rec allFiles2 dir = seq { for file in Directory.GetFiles dir -> file for subdir in Directory.GetDirectories dir ->> allFiles2 subdir } Comprehensions can also be used to construct lists and arrays: let lst = [ for i in 1.. 100 -> (i, i*i) ] let arr = [| for i in 1.. 100 -> (i, i*i) |]

24 1.3.1 Turning files into on-demand sequences let reader = seq { use reader = new StreamReader(File.OpenRead("t.txt")) while not reader.EndOfStream do -> reader.ReadLine() } > reader |> Seq.take 3;; First line... Second line... Third line...

25 1.3.1 Recursive sequences Random walk: let rec randomWalk k = seq { yield k yield! randomWalk (k+rnd.NextDouble()-0.5) } > randomWalk 10.0;; val it: seq = seq [10.0; 10.23817784; 9.956430122; 10.18110362;...] Edit text and revise your documents

26 1.3.2 Asynchronous workflows – fetching pages let museums = [ "MOMA", "http://moma.org/"; "British Museum“, "http://www..../"; "Prado", "http://museoprado.mcu.es" ] let fetchAsync (nm, url: string) = async { do printfn "Creating request for %s..." nm let req = WebRequest.Create(url) let! resp = req.GetResponseAsync() do printfn "Getting response for %s..." nm let stream = resp.GetResponseStream() do printfn "Reading response for %s..." nm let reader = new StreamReader(stream) let! html = reader.ReadToEndAsync() do printfn "Read %d for %s..." html.Length nm }

27 1.3.2 Asynchronous workflows – fetching pages for nm,url in museums do Async.Spawn (fetchAsync(nm, url));; > Creating request for British Museum... Creating request for MOMA... val it : unit = () > Creating request for Prado... Getting response for Prado... Reading response for Prado... Read 1456 for Prado... Getting response for MOMA... Reading response for MOMA... Read 42918 for MOMA... Getting response for British Museum... Reading response for British Museum... Read 22131 for British Museum...

28 1.3.2 Asynchronous workflows – file processing open Microsoft.FSharp.Control open Microsoft.FSharp.Control.CommonExtensions let numImages = 200 let size = 512 let numPixels = size*size let ProcessImageAsync(i) = async { use inStream = File.OpenRead( sprintf "Image%d.tmp" i) let! pixels = inStream.ReadAsync(numPixels) let pixels' = TransformImage(pixels,i) use outStream = File.OpenWrite( sprintf "Image%d.done" i) do! outStream.WriteAsync(pixels') }

29 1.3.2 Asynchronous workflows – file processing let ProcessImagesAsync() = let tasks = [ for i in 1.. numImages -> ProcessImageAsync(i) ] Async.Run (Async.Parallel tasks) |> ignore

30 1.3.4 Other workflows - How do they work? Computation Builders + syntax desugaring

31 2/3 Imperative and object-oriented programming 2 Imperative (loops, mutable cells, exceptions, IO) 3 Object-oriented (classes, interfaces)

32 4 Language-oriented programming Active patterns Provide a way to hide/abstract away internal representations Reflection Quotations A mechanism to access the underlying syntax representation of F# code. LINQ

33 4.1 Active patterns Extensible pattern matching Provide a way to hide/abstract away internal representations open Microsoft.FSharp.Math let (|Rect|) (x:complex) = (x.RealPart, x.ImaginaryPart) let (|Polar|) (x:complex) = (x.Magnitude, x.Phase)

34 4.1 Active patterns > let c = Complex.mkRect(3.0, 4.0);; val c : complex > c;; val it : complex = 3.0r+4.0i > match c with | Rect(x,y) -> printfn "x = %g, y = %g" x y;; x = 3, y = 4 val it : unit = () > match c with | Polar(x,y) -> printfn "x = %g, y = %g" x y;; x = 5.0, y = 0.927295 val it : unit = ()

35 4.2 Reflection Obtaining representations of assemblies, type definitions, and member signatures Via.NET reflection API > let intListType = typeof ;; val intListType : System.Type > intListType.FullName;; val it : string = "Microsoft.FSharp.Collections.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]" Edit text and revise your documents

36 4.3 Quotations A mechanism to access the underlying syntax representation of F# code. let plusExpr = ;; val plusExpr : Expr > plusExpr;; val it : Expr = Edit text and revise your documents

37 4.4 Quotations and LINQ – In-memory objects In-memory objects / collections Native support via aggregate functions let select = Seq.map let where = Seq.filter let people = [| ("Joe", 27, "Sales"); ("Rick", 35, "Marketing"); ("Mark", 40, "Sales"); ("Rob", 31, "Administration"); ("Bob", 34, "Marketing") |] let namesR = people |> select (fun (name, age, dept) -> name) |> where (fun name -> name.StartsWith "R") Edit text and revise your documents

38 4.4 Quotations and LINQ – XML XML Functional construction of XML documents  mutation Edit text and revise your documents

39 4.4 Quotations and LINQ – Linq2Sql Access to query syntax via F# quotations Transform F# quotations to LINQ expressions val SQL : Expr -> 'a let res = SQL <@ { for emp in (#db.Employees) when emp.BirthDate.Value.Year > 1960 && emp.LastName.StartsWith "S" -> (emp.FirstName, emp.LastName) } @> |> take 5 for (first, last) in res do printfn "%s %s" first last Edit text and revise your documents

40 F# Interactive (fsi.exe) Command-line

41 F# Interactive (fsi.exe) Visual Studio plug-in

42 Questions?

43 Reading more about F# Expert F# Apress – 2007 Dec 7 Don Syme, Adam Granicz, Antonio Cisternino

44 Thanks for your attention! Email: granicz.adam@intellifactory.com


Download ppt "F# Introduction to F# Making Programming Functional Adam Granicz IntelliFactory, EPAM Systems."

Similar presentations


Ads by Google