SlideShare uma empresa Scribd logo
1 de 91
Functions rock!Harnessing the Power of Functional Part II: Programming with F# TUTORIAL QCON 2011, London Prof. Dr. Michael Stal Michael.Stal@siemens.com
Objectives of Presentation Introducing core concepts of Functional Programming Introducing F# as example Presentingthe benefits of combining OO and functional programming Illustrating the language in a pragmatic way preferring code over theory But not to cover every available aspect or to cover aspects in full  detail Page 2
Whatis Functional Programming? Praise the Lambda Calculus (which is almost 80 years old) and its successors  (e.g., the typed ones) (Mathematical) Functions Are a means of decomposition Can be assigned to variables  Can be passed as arguments to or returned from functions  Can be anonymous (closures) Emphasize on Immutability:  No side-effects of functions (referential transparency) Values instead of variables   Page 3
Functional ProgrammingLanguages … Are oftenhybrid such as Lisp/Clojure, F#, Scala Use Recursion instead of Iteration Can be strict (eager) or non-strict (lazy) Use  mainly the Typed Lambda Calculus and thus support Pattern Matching Support concepts such as Monads, Continuations Integrate Comprehensions for collection types, Catamorphisms (fold), Anamorphisms (unfold) Page 4
Preconception: Functional LanguagesareSlow Isnottrueanymoredue to: HighlyefficientVMslikethe CLR, JVM StructuralSharing, no naive copying TailCallOptimization: at least someVMs Veryefficient and powerfulLibraries Easy leveraging of Concurrency (e.g., because of immutablity) Page 5
„Nowforsomethingcompletely different“ Introduction to F# 2.0 F# created by Don Syme at Microsoft Research, Cambridge, UK Started at 2002; team also closely associated with introduction of Generics to CLR F# combines Object Oriented Programming with Functional Programming  Page 6 Don Syme,  Source: msdn.microsoft.com/en-us/fsharp/default
Core Properties of F# F# is compatible: runs on CLR/Mono, interoperability with other CLR languages F# is simple and compact: a very small language core with a flat learning curve F# is succinct: More compact code, lower noise-to-signal ratio  F# is high-level: Higher level of abstraction by combining OO with functional programming F# is statically typed: type inference gives F#  the „look&feel“ of a dynamically typed language Page 7 F#‘s Roots: ,[object Object]
ML
OCaml(similar core    language)  ,[object Object],[object Object]
How to obtain F# Source code file may be compiled using fsc: fsc myExample.fs which creates an executable for the CLR You may run an interactive shell by using the following command line instead fsi In this case type the commands directly into the shell using ;; as delimiters You might use Visual Studio 2008 and install F# or Visual Studio 2010 (F# included!) You may use SharpDevelop and F# On Mac OS X, Linux: install Mono, then F# for Mac und Linux add MonoDevelop and the F# Add-In if you prefer an IDE Page 9 For instructions on how to install F# on Mac, Linux: http://functional-variations.net/
Example: Using Visual Studio 2010 Page 10 Solution Explorer Editor Window F# Interactive
F# in a Sandbox URL: http://tryfs.net/ Page 11
F# Type System Basic types from the .NET CLI plus classes, interfaces, generics Function Types, Lambdas Tuples, Lists, Arrays Discriminated Unions Records and Structures Unit (equivalent to void in C++) Option (Monadic Type: Maybe Monad) Delegates Attributes Exceptions Page 12 bool, byte sbyte, int16, uint6, int, uint32, int64, uint64, char, nativeint, unativeint, string,  decimal, unit, void, single, double
let it be The let statement lets you define values Let‘s use the „REPL“ (actually not a REPL; F# is compiled on the fly) Page 13
let for  assigning values Values may be reassigned Mind the difference: the old values are not overwritten, but the identifiers refer to a new value!  Page 14 let x = 5 // val x : int = 5 let x = x + 5 // val x : int = 10 let x = x - 9 // val x : int = 1
let for function definition Using let for giving an anonymous function a name The function definition can also be written as: Page 15 let poly1 = fun x -> 2.0 * x * x - x + 1.0 // => valpoly1 float -> float poly1 1.5 // => val it : float = 4 A closure let poly1 x = 2.0 * x *x - x + 1.0 // => valpoly1 float -> float
UsingClosures in F# Closuresrepresentfirst-classfunctionsthatcontainfree variables They bind free variables to theirdefinitioncontext Page 16 let a = 42 let g x f = f x  printfn "%i" (g 12 (fun i -> a))  // => 42 // But we could also do something like: g 12 (printfn "%i") // => 12 binding Closure
Specifying types is optional due to type inference Type inference allows the compiler to automatically defer the types But you can also specify types explicitly  Page 17 let x : int = 12 let l : int List = [1; 2; 3] let twice (x: float) = 2.0 * x
Special Types: unit unit represents an expression or function with no value Page 18 printfn"QCon 2011 rocks!";;  QCon2011 rocks! type is : valit : unit = () let printHello = printfn“Hello”  type is : valprintHello: unit = ()
Special Types: Option Option is a monadic type (MayBe-Monad) for expressions that either return nothing or a result Applicable to avoid dealing with alternative conditions Page 19 let div a b =     if (b = 0) then None     else Some(a/b) div 6 3 // => Some(2) div 6 0 // => None
let for recursive functions defining a recursive function requires the keyword rec Page 20 let rec fib n =      if (n <= 1)      then 1      else fib(n-1) + fib(n-2) (*   fib 1 => 1  fib 2 => 2  fib 3 => 3  fib 4 => 5  fib 5 => 8 *)
Mutual Recursion defining mutual recursive functions Page 21 let rec f1 x =     if (x <= 1)         then 1         else f2(x) and f2 x =       if (x % 2 = 0)         then f1(x/2)         else f1(x/2 - 1) printfn "%i" (f1 18) // => 1
Currying and Partial Function Application F# supports partial function application: Page 22 > let mult x y = x * y;; valmult : int -> int -> int > let double x = mult 2 x;;  val double : int -> int > double 3;; val it : int = 6 > double 4;; val it : int = 8 double is defined as  partial application of mult with first param 2
Lazy evaluations F# supports lazy evaluations Lazy means: the value is only calculated on demand Powerful usage for collections (see later) Page 23 let r  = lazy               ( let tmp = 2 * 21 printfn "Calculating" tmp              ) printfn "%d" (r.Force())  // => Calculating //    Forced evaluation 42
Functions can be locally nested within functions Note: In F# like in all functional languages there are no statements but expressions Expressions always return values. The last value is used as the result of the expression like sum(a,b,c) / 3 in the example: Page 24 // using lightweight syntax: #light let avg (a,b,c) =     let sum(a,b,c) = a + b + c     sum(a,b,c) / 3 let d = avg(1,2,3)  printfn “and the average is %i” d // => 2
Operator Overloading in F# It is possible to define/overload operators Code Example:  Page 25 let (*) a b = a + b let a = 2 * 7 // => a = 9 // may also be used in prefix notation: (*) 2 6 // => 8 // for unary operators: let (~-) n = 1 – n - 88 // => -87
Exceptional F# raise used to raise exception of appropriate exception type try/with and try/(with/)finally both available Exceptions can also be raised with: failsWith “Wrong input“ Page 26 exceptionEvenArgument of int let printNumber n =     if (n % 2 = 0)          then raise (EvenArgument  n)         else printfn "%i" n try  printNumber5 // ok printNumber4 // => exception EvenArgument 4  with EvenArgument x -> printfn "Number %i is even!" x
The Pipeline Operator |> The pipeline |> operator is very powerful let (|>) x f = f x // applyfunction f to x There is also a <|operator (processing right to left)  which is only seldomly used The pipeline operator unfolds its real power with all the sophisticated collection types Page 27 let x = sin 1.0 // or: let x = 1.0 |> sin
Using Units of Measure F# allows to assign units of measure  Compiler checks for compatibility Remember: Some big aeronautics and space projects failed due to such errors  Page 28 [<Measure>] type m // meter [<Measure>] type s // second // let a = 5.0<m> + 7.3<s> =>compiler error let distance = 100.0<m> let time = 5.0<s> let speed = (distance/time) let distanceInAnHour = speed * 3600.0<s>
Mutable F# Use the keyword mutable for defining real variables The F# API also supports ref. This denotes a record which contains a mutable element. Use ! to retrieve contained value and := to override Note: for some types mutable cousins exist Page 29 > let mutable a = 41;; val mutable a : int = 41 > a <- 42;; val it : unit = () > a;; val it : int = 42 > let i = ref(0);; val i : int ref = {contents = 0;} > i := !i + 42;; val it : unit = () > !i;; val it : int = 42
Arrays According to MSDN/F#: Arrays are fixed-size, zero-based, mutable collections of consecutive data elements that are all of the same type Arrays can be created in several ways. Examples: Page 30 // specifying the elements let names = [| "Mick"; "Keith"; "Mark" |] // sequence expressions let squares = [| for i in 1..10 -> i * i |] // initialized array: 10 elems with 0 let ai : int array = Array.zeroCreate 10 // multidimensional 3 x 3 array let matrix : int array[,] = Array2D.zeroCreate 3 3
Basic Array Operations Several basic operations are provided for arrays For example, operations to access parts of an array or operations to create new arrays Page 31 // get slice let subarr = squares.[3..5] // get element  printfn "%d" ai.[2] // modify element ai.[2] <- 6
Sophisticated Array operations There are also lots of more sophisticated operations for arrays that are also available for other kinds of collections Examples include fold, collect, concat, rev and more: Page 32 let a1 = [|1; 2; 3|]  let a2 = [|4; 5; 6 |] let a12 = Array.concat [a1; a2] // new array! [| 1 .. 10 |] // array containing 1,2,3,..,10 |> Array.filter (fun elem -> elem % 2 = 0) // even // for numbers n but 8 put Some(n * n) into array: |> Array.choose (fun elem -> if (elem <> 8) then                          Some(elem*elem) else None) |> Array.rev// revert sort order |> printfn "%A" //=> [|100; 36; 16; 4|]
Using Namespaces and Modules Using the .NET Framework Classes is straightforward  You may import namespaces using open Namespaces are defined in F# with namespace, modules with module Namespaces mustn‘t define values Page 33 open System.Windows.Forms let form = new Form (Visible=true, Text="QCon 2011") let button = new Button(Text ="Click me") button.Click.Add (fun _ -> printfn "Hello, London!") form.Controls.Add(button) form.BackColor <- System.Drawing.Color.Azure Application.Run form
Modules F# Modulescancontainvalues, typedefinitions, submodules Modulesarecompiled as classeswithstaticmembers Page 34 moduleMathModule letrechcf (a:bigint) (b:bigint) =  if a = 0I then b elif (a < b) thenhcf a (b-a) elsehcf (a-b) b type Rational(a: bigint, b: bigint) = let n = hcf a b memberr.a = a / n  memberr.b = b / n staticmember (+) r1 r2 = …
Implicit Generics F# applies type inference for each definition If it cannot assign types it will treat the definition as a generic definition with type parameters In the example above the type parameter is 'a Let us instantiate the definition: Page 35 > let makeList a b = [a; b] => valmakeList : 'a -> 'a -> 'a list makeList 1 2 => valit : int list = [1; 2]
Explicit Generics But you can also specify the types implicitly Likewise, we can specify the type on usage Page 36 ,[object Object],     [a; b];; => val makeListExp : 'T -> 'T -> 'T list makeListExp<int> 1 2;; => valit : int list = [1; 2]
Tuples Tuples are very convenient for various applications Page 37 let x = ( 1, 2)     // val x : int * int = (1, 2) let a, b = x     // val b : int = 2     // val a : int = 1 let ad = ("Adam", 7)     // val ad : string * int = ("Adam", 7) let swap (a,b) = (b,a)     // val swap : 'a * 'b -> 'b * 'a
Sets sets are used for various problems Page 38 open System let s : Set<int> = Set(seq{ 1..7 }) let t = set[1;2;3] Console.WriteLine(s.Count) Console.WriteLine(s.MaximumElement) Console.WriteLine(s.IsProperSubsetOf(Set(seq{ 1..10 }))) Console.WriteLine(s.IsProperSupersetOf(t)) Console.WriteLine(s) let sl = Set.toList s // make a list
Maps Maps (hash tables, dictionaries) are used as follows:  Page 39 let m =  Map.empty         .Add("Syme", "F#")         .Add("Stroustrup", "C++")         .Add("Gosling", "Java")         .Add("McCarthy", "Lisp") match m.TryFind("Syme") with     |   None -> printfn "not found"     |   Some(lng) -> printfn "%s" lng // F# Console.WriteLine(m.["McCarthy"]) // Lisp
Land of Lists Lists are the core datatype of all functional languages F# provides excellent support for lists Page 40 let l = [] // empty list let l2 = "Hello" :: ", " :: l // add elements at the head  let l3 = ["London"] let l4 = l2 @ l3 // concatenate two lists let l5 = l4 @  ["!";"!"]  let l6 = List.rev l5 // reverse order printfn "%A" l5 => [“Hello”;”, “;”London”;”!”;”!”]
And even more on Lists Several additional functions provided for lists In addition, List contains many static members Page 41 let l = [ 'a'; 'b'; 'c'; 'd' ] printfn "%c" l.Head   // => a printfn "%A" l.Tail   // => [‘b’;’c’;’d’] printfn "%d" l.Length // => 4 let lzip = List.zip [1; 2; 3] ['a';'b';'c'] printfn "%A" lzip // => [(1, 'a'); (2, 'b'); (3, 'c')] let arr =  List.toArraylzip // make array
Pattern Matching Pattern matching eases processing in functional languages It is applicable for all data types but is particularly valuable for collections Page 42 let rec addNumbers (l : 'int List) =     match l with | [] -> 0     | head :: tail -> head + addNumbers tail let l = [1; 2; 3; 4; 5] let sum = addNumbers l printfn "%i" sum => 15
Detour: General Pattern Matching  Pattern matching allows to analyze arguments for their value or type Appears to be a Java/C# switch on stereoids, but is much more powerful, especially when dealing with collection types The :? operator defines a dynamic type test Note there are also operators for static upcast  (e.g., 1 :> obj ) and dynamic downcast  (e.g., shape :?> circle) in F# Page 43 let reportObject (x: obj) =     match x with     | :? string as s -> printfn"string '%s'" s     | :? int as d -> printfn"integer '%d'" d     | :? float as f -> println “float ‘%f’” f      | _ -> printfn“unknown"
Detour: General Pattern Matching using When clauses  when allows to further check an argument during pattern matching Page 44 let i = -12 match i  with     | _ when i > 0 -> printfn "positive"     | _ when i < 0 -> printfn "negative"     | _ -> printfn "zero“
Detour: The wildcard _ In F# _ serves as a wildcard character Always used when you like to ignore parts of an expression Another example: ignoring parameters Page 45 match groups with     | // pattern matching 1 | _ :: rest -> findFSharpUGs rest     | [] -> printfn "end of list" let apply f x = f x printfn "%i" (apply (fun _ -> 42) 12) // => 42
Operations on Collections: map There are several operations for collections that reveal the power of functional programming.  The most prominent example is map   Page 46 let l = [1; 2; 3; 4; 5] let l2 = List.map (fun x -> x * x) l printfn "%A" l2 // => [1; 4; 9; 16; 25] Apply the function (1st param) to all arguments of the list (2nd param) and create a new list from the results
Operations on Collections: filter With filter you can filter elements from a list Useful to create views on lists Page 47 let l = ["Martin"; "Erich"; "Kent";          "Gregor"; "Kevlin"] let view = l |> List.filter(fun elem->             elem.StartsWith("K")) printfn "%A" view // => [“Kent”; “Kevlin”] Put all those elements that fulfil the  condition into the result list
Operations on Collections: fold With foldand foldbackyou may iterate through a collection (from left to right respecitely from right to left) and apply a function Let me give you an example fold takes the current element in the collection it has iterated to, applies the specified function on the accumulator and this element, and passes the result to the next iteration as new accumulator This can be used , for instance, to add all numbers in the collection as depicted in the example Page 48 let l = [1 ; 2; 3; 4; 5 ] let sum a i =  a + i let result = List.foldsum 0 l printfn "result is %i" result // => 15 collection function Intitial value for accumulator
UsingPipeliningwithCollections = Power! Here the power of the pipeline operator can be leveraged Pipelining also improves readability Page 49 let l = [1; 2; 3; 4; 5] let l2 =       l |> List.map (fun x -> x * x) |> List.rev printfn "%A" l2 // => [25; 16; 9; 4; 1] Take the list, apply the operation to all of Its elements, and revert the list
List Comprehensions In functional programming recursion and comprehensions compensate for imperative loops Lists can be easily generated using comprehensions Sequences in F# are collections of typeIEnumerable They are subject to lazy evaluation! let s = seq { for i in 1 .. 10 do yield i + 1 } Page 50 // all values from 1 to 10 let l1 = [ 1 .. 10 ] // all values from 1 to 9 in steps of 2 let l2 = [ 1 .. 2 .. 9 ] // all squares for n from 1 upto10  let l3  =  [for n in 1 .. 10 do yield  n * n]
Unfold on Sequences Unfold generates a sequence using a function (opposite of fold) (´State -> ´T * ´State option) -> ´State -> seq<´T> Take current state and return an option tuple with next element of sequence and next state The initial state value Generated sequence Page 51 let fibI = Seq.unfold( fun state ->       Some(fst state + snd state, (snd state, fst state            + snd state)) )(1I,1I) let tmp = fibI |> Seq.take100 for x in tmp do System.Console.WriteLine x
Records Records are similar to tuples In records, however, fields are named Field names become accessors of the record type Page 52 type usergroup = { topic: string; members: string list } let fs_fans = { topic = "F#"; members =      [ "Don"; "Michael"; "Ted"] } printfn"topic is %s " fs_fans.topic printfn "members: %A " fs_fans.members // => topic is F# //    members: ["Don"; "Michael"; "Ted"]
Cloning Records You can clone records and overwrite their fields partially using with Page 53 type person =     { name : string; prefnum: int } let douglas =     { name = "douglas";prefnum= 42 } let michael =     { douglas with name = "michael"} printfn "%s %d" michael.name michael.preferred_num
Records and Pattern Matching Alternatively you may use pattern matching for accessing and checking fields Page 54 type usergroup = { topic: string; members: string list } let cs_DE =   {topic = "C#"; members = ["Tim"; "Tom; Pit" ]} let fs_FR =    {topic = "F#"; members = [ "Henry"; "Marc"; "Bert" ]} let rec findFSharpUGs (groups: usergroup list) =     match groups with     | { topic = "F#"; members = m } :: rest         -> printfn "%A" m findFSharpUGs rest     | _ :: rest -> findFSharpUGs rest     | [] -> printfn "end of list" findFSharpUGs[cs_DE; fs_FR]
Discriminated Unions One of the core type constructs in F# Aggregates different structures The name after | is called a constructor or discriminator Page 55 type Content = string type BinTree =      | Node of BinTree * BinTree     | Leaf of Content // example usage: let bLeft  = Node(Leaf("1.1"), Leaf("1.2")) let bRight = Leaf("2.1") let b  = Node(bLeft, bRight)
Discriminated Unions and Pattern Matching ... Best served with Pattern Matching Page 56 let rec treePrint b = match b with     | Node(bl,br) -> printf "("  treePrintbl printf "|" treePrintbr printf ")"     | Leaf(c) -> printf "[%s]" c treePrint b //=>(([1.1]|[1.2])|[2.1])
Example: Functions as Types Functions are also types. Let‘s implement the Command pattern in F# Page 57 type Command = Command of (int -> int) let command1 = Command(fun i -> i + 1) let command2 = Command(fun i -> i * i) let command3 = Command(fun i -> i / 3) let rec exec commands =     match commands with     | [] -> printf "end"     | Command(f) :: r -> let res = f 6 printfn "%i" res                          exec r // recursion on rest let cmdseq= [command1; command2; command3] exec cmdseq// => 7 <cr> 36 <cr> 2
Detour: Acquiring and Disposing Resources withuse Theuseoperator in F# behavessimilar to using in C# Whenacquiring a resource, use will makesurethatthe Disposemethodiscalled (objecttypemustimplementIDisposable) Whenthescope of theobjectisleft, no matter how, theresource will getdeleted Page 58 let writeAText () = useotf = 		File.CreateText(@“QCON2011.txt") otf.WriteLine(“F# is fun!")
Enums Enums in F# areexpressedsimilar to discriminatedunions Page 59 type Ratings =     | Excellent = 10     | Good = 7     | Average = 5     | Fair = 3     | Bad = 1
Mutual Recursive Types Types in F# can not refer to types defined in a later part You need to have a mutual recursive definition using and  Page 60 type Element =     | Content of string     | Ref of Tree // Error: Tree not defined type Tree =     | Node of Tree * Element * Tree     | Leaf of Element	 type Element =     | Content of string     | Ref of Tree and Tree =     | Node of Tree * Element * Tree     | Leaf of Element
Extend Pattern Matching with Active Patterns For extending pattern matching you may define yourown patterns This is done using active patterns as shown in the example: Page 61 type Coordinate(x : float, y : float) =     member c.x = x     member c.y = y     member c.r= Math.Sqrt(c.x**2.0+c.y**2.0)     member c.a= Math.Atan(c.y / c.x) let (|Polar|) (c : Coordinate) = (c.a, c.r) let printPolar c =     match c with     | Polar(a, r) -> printfn "a=%f  r=%f" a r printPolar(new Coordinate(1.0,1.0))
Another Example for Active Patterns We can even provide patterns for existing (.NET) types Page 62 let (|Int|Float|String|) (o : Object)  =      match o with     | :? string -> String("42")     | :? float -> Float(42.0)     | :? int -> Int(42) let rec print42 (o : Object) =     match o with     | String(s) -> Console.WriteLine("String : {0}",s)     | Float(f)  -> Console.WriteLine("Float : {0}",f)     | Int(i) -> Console.WriteLine("Int : {0}",i) print42 "universe" // => String : 42
Partial Active Patterns Partial patterns return Options Page 63 let (|Even|_|) n =      if (n % 2 = 0) // n mod 2 = 0     then Some(n) // yes => return Some(val)     else None // no => return None let checkEven n =     match n with     | Even(m) -> printfn "even"     | _ -> printfn "odd" checkEven 12 // “even” checkEven 13 // “odd”
Keywordfunction For patternmatching an interestingshortexistsusingthekeywordfunction Page 64 // instead of: let rec combine2String sep s =     match  s with     | [] -> ""     | h :: t ->  h.ToString() +  sep + combine2String sep t printfn "%s" (combine2String " " ["Hello ";"QCon"]) // you may also use: let rec combine2String’ sep = function     | [] -> ""     | h :: t ->  h.ToString() +  sep + combine2String’ sep t printfn "%s" (combineToString’ " " ["Hello ";"QCon"])
On the Road to OOP F# supports object-oriented programming The first step to OOP is assigning functionality to objects Page 65 type Name  =     { first: string;     middle : char;     last: string }     with         override x.ToString() = x.first + " " +  x.middle.ToString() + " " + x.last         member x.printName = printfn "%s“                                                  (x.ToString()) let JFK : Name  = { first = "John"; middle = 'F';  last = "Kennedy" } JFK.printName // => John F Kennedy
Object Expressions We can also instantiate interfaces within a variable definition In the next slides we‘ll dive deeper into classes/interfaces in F# Page 66 open System open System.Collections.Generic let comparer = {     new IComparer <string> with // sort by length!         member x.Compare(s1, s2) =              let s1Len = s1.Length             let s2Len = s2.Length             s1Len.CompareTo(s2Len) } let a = [|"Peter"; "Mike"; "Tim"|]  Array.Sort(a, comparer) // arrays are mutable! printfn"%A" a // => [| "Tim“; "Mike"; "Peter"|]
DefiningClasses in F# Classes in F# offerthesamecapabilities such as in C# For membersweneed to specify a instancename Page 67 type Circle (radius : float, center: float * float) = static let UnitCircle=   Circle(1.0,                                  (float 0, float 0)) member v.scale(k) = Circle(k * radius,  center)     member v.radius = radius     member v.center = center static member unitCircle = UnitCircle override v.ToString() =         "r = " + v.radius.ToString() + " and c = " +  v.center.ToString() let c = Circle(2.0, (3.0,4.0)) System.Console.WriteLine c
Explicit Fields letbindingsalwaysrequireinitialization Ifyou do notneed an initialization,useexplicitvaluesinstead! Theattribute[<DefaultValue>] isrequiredforvaluesthatshould will beinitialized to zero.  For typeswithoutzeroinitializationwemustsetfields in theconstructor Page 68 type Book (author : string, title : string) = [<DefaultValue>] val mutable rating : float [<DefaultValue>] val mutable readers : int     member b.rate(current : float) = b.readers <- b.readers + 1 b.rating  <- (b.rating + current) / b.readers let fSharpBook = new Book (“Don Syme”, “Expert F#”) fSharpBook.readers <- 0 fSharpBook.rating <- 0.0
Abstract Classes Abstract typesresp.classesmusthave an attributeAbstractClass Derivingfrom a baseclassrequirestheinheritkeyword Page 69 [<AbstractClass>] type Shape() =     abstract draw: unit -> unit type Circle (radius : float, center: float * float) =     inherit Shape()     // all the other members  default v.draw() = printfn "%s" (v.ToString()) Useoverrideforoverridingimplementations and defaultforoverriding an abstractmethod
VisibilityAnnotations F# support private, public, internalvisibility Also applicable to modules Page 70 Thisishowyou canaddmore constructors type SpaceShip(name : string) =     new() = new SpaceShip("NCC-1701")     member private s.name = name     member internals.speed = ref(0)     member publics.call(msg : string) =  printfn "Got message %s" msg     member publics.accelerate() =         if (!s.speed < 8) then s.speed := !s.speed + 1     member public s.stopEngines() = s.speed := 0 member s.id          with get() = s.name         // and set(id) =  ... if it were mutable
Default and Optional Parameters In F# 2.0 types, functions can have default and optional parameters In functions optional parameters have Option type! Page 71 open System type CoolProgrammingLanguage(?name : string, ?compile : bool) = let name = defaultArg name "F#" // default value     let compile = true // optional parameter     member x.Name = name     member x.Compile = compile let fsharp = new CoolProgrammingLanguage() // returns F# and true: Console.WriteLine(fsharp.Name + " " + fsharp.Compile.ToString())
Defining and Using Interfaces Interfaces aredefined as abstracttypeswithonlyabstractmembers Usingthem in a classrequirestheinterfacekeyword Page 72 type IDraw =     abstract draw: unit -> unit type Line(p1 : float * float, p2: float * float) =     member l.p1 = p1     member l.p2 = p2 interface IDraw with         member l.draw() =              let lineWeight =  2             // ........... printfn "done"
ObjectExpressions and Interfaces Youmay also instantiate an interfacedirectly in a function Page 73 typeIDraw = abstractdraw: unit -> unit let point(p : float * float) = { newIDrawwith         member x.draw() = printfn "drawing the line" } point(2.0, 3.0).draw() // => drawingtheline
Page 74 Advanced F#
Continuations Continuationsbasicallyis „a function that receives the result of an expression after it’s been computed“ Page 75 // instead of writing let x = 3 let y = 4 let e1 = x * y  let e2 = e1 + 1 // we pass the continuation as an argument to  // a function that takes the result and continues the  // evaluation. This is an inside-out approach: let cont_e cont = cont (x * y)  let e3 = cont_e (fun i -> i + 1)
ContinuationPassing Style (CPS) Butwhyshouldwecareabout CPS? Letususethefollowingexample Problem: this can‘t be subject to TCO (Tail Call Optimization) Works well forbalancedtreesbutnotforunbalancedones Solution: add an accumulator as extra argument Page 76 type Tree = 	| Node of string * Tree * Tree 	| Tip of string let rec size tree = 	match tree with 		| Tip _ -> 1 		| Node(_,treeLeft,treeRight) -> 			size treeLeft + size treeRight
CPS CaseStudy: Using an extra accumulator We just add an extra parameter and weassume (!) thetreeisskewed to the right (1 of 2 options) The call recursing over the right branch is a tail call, the left one isn‘t Thus, we still risk a stack overflow for trees that are more skewed to the left Page 77 let recsizeAcc acc tree = 	match tree with 		| Tip _ -> 1 + acc 		| Node(_,treeLeft,treeRight) -> 			let acc = sizeAcc acc treeLeft sizeAcc acc treeRight let size tree = sizeAcc 0 tree
CPS CaseStudy: UsingContinuations Byusingcontinuations all branches will betail-calls Thestackoverflowproblem has beeneliminated Page 78 let recsizeCont tree cont = 	match tree with 	| Tip _ -> cont 1 	| Node(_,treeLeft,treeRight) -> sizeConttreeLeft (fun leftSize -> sizeConttreeRight (fun rightSize -> 				cont (leftSize + rightSize))) let size tree = sizeCont tree (fun x -> x)
Reactive, Asynchronous and Parallel F# Manythingswithin an applicationhappenasynchronously, such as Reading Web Pages Processing a GUI eventhandler Waitingfor I/O completion In addition, weshouldleveragethe power of Multicore CPUs  Weneedlanguagesupportforreactive, asynchronous, and parallel processing Page 79 SocketforAthlon 64 X2 CPU Source: Wikipedia
Using Mechanisms from the BCL In the .NET BCL (Base Class Library) there are already some mechanisms available such as threads and background workers We instantiate a BackgroundWorker from a pool of threads:        let worker = new BackgroundWorker() We then pass a function with code to the worker it should execute: worker.DoWork.Add(fun args -> .....) In the next step we tell the worker which code to execute after its completion. An event will automtaically raised by the runtime .                                           worker.RunWorkerCompleted.Add(fun args-> ...) Finally we start the worker‘s execution which raises an event to start DoWork:                                                                 worker.RunWorkerAsync() Page 80
Complete Example: Calculating the nth Fibonacci  Page 81 let worker = new BackgroundWorker() let numIterations = 1000 worker.DoWork.Add(fun args ->     let rec computeFibonacciresPrevPrevresPrev i =         let res = resPrevPrev + resPrev 	  if i = numIterations then args.Result <- box res //  mutable access         else computeFibonacciresPrev res (i+1) computeFibonacci 1 1 2) worker.RunWorkerCompleted.Add(fun args -> MessageBox.Show(sprintf "Result = %A" args.Result) |> ignore) worker.RunWorkerAsync()
Async Example Microsoft.FSharp.Control.Async<'T> allows to define asynchronous workflows An Async instance will provide a result in the future (calling Start) let!, do!, return!, yield! imply asynchronous processing Page 82 let fetchAsync(url:string) = async {         let req = WebRequest.Create(url) let! resp = req.AsyncGetResponse()         let resp = req.GetResponse         let stream = resp.GetResponseStream()         let reader = new StreamReader(stream) let! html = reader.AsyncReadToEnd() printfn "Read %d characters for %s..."  html.Lengthurl} Async.Start (fetchAsync(“http://fsharp.net”))
Async - Under the Hood Internally, F# uses continuations. For example: will be implemented as Page 83 async { let req= WebRequest.Create("http://fsharp.net/")    let! resp = req.AsyncGetResponse()     let stream = resp.GetResponseStream()     let reader = new StreamReader(stream)     let! html = reader.AsyncReadToEnd()     html } async.Delay(fun () ->     let req = WebRequest.Create("http://fsharp.net/") async.Bind(req.AsyncGetResponse(), (fun resp ->         let stream = resp.GetResponseStream()         let reader = new StreamReader(stream) async.Bind(reader.AsyncReadToEnd(), (fun html -> async.Returnhtml)))
An Example for Parallel Execution Page 84 open System.Threading open System let parallelArrayInit n f = let currentLine = ref -1 // reference     let res = Array.zeroCreate n     let rec loop () =         let y = // locking with Interlocked Interlocked.Increment(&currentLine.contents)         if y < n then res.[y] <- f y; loop() Async.Parallel[ for i in 1 ..  Environment.ProcessorCount-> async{do loop()} ]         |> Async.Ignore         |> Async.RunSynchronously res let rec fib x=if x < 2 then 1 else fib(x-1)+fib(x-2) let it = parallelArrayInit 25 (fun x -> fib x) printfn "%A" it // => [|1; 1; 2; 3; 5; 8; 13; 21; 34; 55; 89; ... |]
Agent-based Programming The class MailboxProcessor allows to implement agents which retrieve messages through their inbox Page 85 let counter =     new MailboxProcessor<_>(fun inbox -> let rec loop n = async{  printfn "n = %d, waiting..." n                 let! msg = inbox.Receive()                 return! loop (n+msg)              }         loop 0) Counter.Start() // enter loop in asynchronous agent Counter.Post(42) // send message “42” to agent
Summary F# pragmatically combines imperative (C# roots)  with functional programming (OCaml roots) It runs on the CLR and thus offers interoperability with other CLI languages Excellent features for concurrency and asynchronous operation F# programs are compact and succinct causing less noise-to-signal ratio Support for Windows, Mac OS, Linux Availability on Visual Studio 2010 implies Microsoft is serious about functional languages Start Coding with F#! Page 86
Books: My Recommendations D. Syme, A. Granicz, A. Cisternino: Expert F# 2.0 (Expert's Voice in F#), Apress; edition (June 7, 2010)  C. Smith: Programming F#: A comprehensive guide for writing simple code to solve complex problems (Animal Guide), O'Reilly Media; edition (October 13, 2009) T. Petrícek, J. Skeet: Real World Functional Programming: With Examples in F# and C#, Manning Publications; edition (December 30, 2009) A lot of more books available Page 87
F# Tools  Lot of more available F# PowerPack: tools such as FsLex, FsYacc, (P)LINQ support, additional classes, SI Units for Measure, ... Amazing examples on http://code.msdn.microsoft.com/fsharpsamples xUnit.net for Unit Testing: http://xunit.codeplex.com/ or Nunit F# Web Tools: http://fswebtools.codeplex.com/ Page 88
F# Links Interesting Links to F# information/sources Microsoft Research: http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/ Microsoft MSDN: http://msdn.microsoft.com/en-us/fsharp/default Don Symes Web Log: http://blogs.msdn.com/b/dsyme/ F# Community Samples: http://fsharpsamples.codeplex.com/ hubFS – The Place for F#: http://cs.hubfs.net/ Thomas Petricek: http://tomasp.net/ F# Blog by Jon Harrop: http://fsharpnews.blogspot.com/ TechED präsentation by Don Syme: http://blogs.msdn.com/b/dsyme/archive/2010/11/29/my-talk-at-teched-europe-2010-a-taste-of-f-today-and-future.aspx YouTube: http://www.youtube.com/watch?v=uyW4WZgwxJE Page 89
Summary F# pragmatically combines imperative (C# roots)  with functional programming (OCaml roots) It runs on the CLR and thus offers interoperability with other CLI languages Excellent features for concurrency and asynchronous operation F# programs are compact and succinct causing less noise-to-signal ratio Support for Windows, Mac OS, Linux Availability on Visual Studio 2010 implies Microsoft is serious about functional languages Start Coding with F#! Page 90

Mais conteúdo relacionado

Mais procurados (19)

C# in depth
C# in depthC# in depth
C# in depth
 
Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)Why Java Sucks and C# Rocks (Final)
Why Java Sucks and C# Rocks (Final)
 
Oops presentation
Oops presentationOops presentation
Oops presentation
 
DIWE - Fundamentals of PHP
DIWE - Fundamentals of PHPDIWE - Fundamentals of PHP
DIWE - Fundamentals of PHP
 
Javascript
JavascriptJavascript
Javascript
 
Introduction to C++
Introduction to C++Introduction to C++
Introduction to C++
 
C by balaguruswami - e.balagurusamy
C   by balaguruswami - e.balagurusamyC   by balaguruswami - e.balagurusamy
C by balaguruswami - e.balagurusamy
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Java8
Java8Java8
Java8
 
C++ Programming
C++ ProgrammingC++ Programming
C++ Programming
 
C# / Java Language Comparison
C# / Java Language ComparisonC# / Java Language Comparison
C# / Java Language Comparison
 
DITEC - Programming with Java
DITEC - Programming with JavaDITEC - Programming with Java
DITEC - Programming with Java
 
ParaSail
ParaSail  ParaSail
ParaSail
 
Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.
 
Scala
ScalaScala
Scala
 
Swift, swiftly
Swift, swiftlySwift, swiftly
Swift, swiftly
 
Modern C++
Modern C++Modern C++
Modern C++
 
SRAVANByCPP
SRAVANByCPPSRAVANByCPP
SRAVANByCPP
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 

Destaque

全てのページにcanonicalを!
全てのページにcanonicalを!全てのページにcanonicalを!
全てのページにcanonicalを!Kaori Kotobuki
 
Accu2010 archrefactoring
Accu2010 archrefactoringAccu2010 archrefactoring
Accu2010 archrefactoringMichael Stal
 
ZenbackとWordPressのイイ関係
ZenbackとWordPressのイイ関係ZenbackとWordPressのイイ関係
ZenbackとWordPressのイイ関係Kaori Kotobuki
 
$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGD
$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGD$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGD
$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGDKaori Kotobuki
 
Movable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015d
Movable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015dMovable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015d
Movable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015dKaori Kotobuki
 
Power of Social network on your site with zenback
Power of Social network on your site with zenbackPower of Social network on your site with zenback
Power of Social network on your site with zenbackKaori Kotobuki
 

Destaque (7)

全てのページにcanonicalを!
全てのページにcanonicalを!全てのページにcanonicalを!
全てのページにcanonicalを!
 
Accu2010 archrefactoring
Accu2010 archrefactoringAccu2010 archrefactoring
Accu2010 archrefactoring
 
ZenbackとWordPressのイイ関係
ZenbackとWordPressのイイ関係ZenbackとWordPressのイイ関係
ZenbackとWordPressのイイ関係
 
$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGD
$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGD$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGD
$whoami kaoritter at Tokyo girl geek dinners 2013 #TGGD
 
Hund+Katze
Hund+KatzeHund+Katze
Hund+Katze
 
Movable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015d
Movable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015dMovable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015d
Movable Typeでニンテンドー3DSの課題を解決!?またはSix Apart エンジニア求人募集 #cross2015 #cross2015d
 
Power of Social network on your site with zenback
Power of Social network on your site with zenbackPower of Social network on your site with zenback
Power of Social network on your site with zenback
 

Semelhante a Qcon2011 functions rockpresentation_f_sharp

F# Intro for Scala Developers
F# Intro for Scala DevelopersF# Intro for Scala Developers
F# Intro for Scala Developersfsug
 
Functional Programming in C# and F#
Functional Programming in C# and F#Functional Programming in C# and F#
Functional Programming in C# and F#Alfonso Garcia-Caro
 
Functional programming with FSharp
Functional programming with FSharpFunctional programming with FSharp
Functional programming with FSharpDaniele Pozzobon
 
Introduction to C Language - Version 1.0 by Mark John Lado
Introduction to C Language - Version 1.0 by Mark John LadoIntroduction to C Language - Version 1.0 by Mark John Lado
Introduction to C Language - Version 1.0 by Mark John LadoMark John Lado, MIT
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n
name name2 nname name2 n
name name2 ncallroom
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.pptcallroom
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmersamiable_indian
 
name name2 n2
name name2 n2name name2 n2
name name2 n2callroom
 

Semelhante a Qcon2011 functions rockpresentation_f_sharp (20)

F# 101
F# 101F# 101
F# 101
 
Introduction to F#
Introduction to F#Introduction to F#
Introduction to F#
 
Introduction to F# 3.0
Introduction to F# 3.0Introduction to F# 3.0
Introduction to F# 3.0
 
F# Intro for Scala Developers
F# Intro for Scala DevelopersF# Intro for Scala Developers
F# Intro for Scala Developers
 
Functional Programming in C# and F#
Functional Programming in C# and F#Functional Programming in C# and F#
Functional Programming in C# and F#
 
Lập trình C
Lập trình CLập trình C
Lập trình C
 
Functional programming with FSharp
Functional programming with FSharpFunctional programming with FSharp
Functional programming with FSharp
 
Introduction to C Language - Version 1.0 by Mark John Lado
Introduction to C Language - Version 1.0 by Mark John LadoIntroduction to C Language - Version 1.0 by Mark John Lado
Introduction to C Language - Version 1.0 by Mark John Lado
 
ppt7
ppt7ppt7
ppt7
 
ppt2
ppt2ppt2
ppt2
 
name name2 n
name name2 nname name2 n
name name2 n
 
test ppt
test ppttest ppt
test ppt
 
name name2 n
name name2 nname name2 n
name name2 n
 
ppt17
ppt17ppt17
ppt17
 
ppt30
ppt30ppt30
ppt30
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.ppt
 
ppt18
ppt18ppt18
ppt18
 
Ruby for Perl Programmers
Ruby for Perl ProgrammersRuby for Perl Programmers
Ruby for Perl Programmers
 
ppt9
ppt9ppt9
ppt9
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 

Último

Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1GloryAnnCastre1
 
Scientific Writing :Research Discourse
Scientific  Writing :Research  DiscourseScientific  Writing :Research  Discourse
Scientific Writing :Research DiscourseAnita GoswamiGiri
 
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptxMan or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptxDhatriParmar
 
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptxBIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptxSayali Powar
 
Oppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmOppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmStan Meyer
 
4.11.24 Mass Incarceration and the New Jim Crow.pptx
4.11.24 Mass Incarceration and the New Jim Crow.pptx4.11.24 Mass Incarceration and the New Jim Crow.pptx
4.11.24 Mass Incarceration and the New Jim Crow.pptxmary850239
 
Textual Evidence in Reading and Writing of SHS
Textual Evidence in Reading and Writing of SHSTextual Evidence in Reading and Writing of SHS
Textual Evidence in Reading and Writing of SHSMae Pangan
 
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...DhatriParmar
 
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptxDecoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptxDhatriParmar
 
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxDIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxMichelleTuguinay1
 
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Association for Project Management
 
Multi Domain Alias In the Odoo 17 ERP Module
Multi Domain Alias In the Odoo 17 ERP ModuleMulti Domain Alias In the Odoo 17 ERP Module
Multi Domain Alias In the Odoo 17 ERP ModuleCeline George
 
ICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdfICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdfVanessa Camilleri
 
How to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 DatabaseHow to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 DatabaseCeline George
 
Q-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITWQ-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITWQuiz Club NITW
 
Active Learning Strategies (in short ALS).pdf
Active Learning Strategies (in short ALS).pdfActive Learning Strategies (in short ALS).pdf
Active Learning Strategies (in short ALS).pdfPatidar M
 
Grade Three -ELLNA-REVIEWER-ENGLISH.pptx
Grade Three -ELLNA-REVIEWER-ENGLISH.pptxGrade Three -ELLNA-REVIEWER-ENGLISH.pptx
Grade Three -ELLNA-REVIEWER-ENGLISH.pptxkarenfajardo43
 
Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4JOYLYNSAMANIEGO
 
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)lakshayb543
 
31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...
31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...
31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...Nguyen Thanh Tu Collection
 

Último (20)

Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1Reading and Writing Skills 11 quarter 4 melc 1
Reading and Writing Skills 11 quarter 4 melc 1
 
Scientific Writing :Research Discourse
Scientific  Writing :Research  DiscourseScientific  Writing :Research  Discourse
Scientific Writing :Research Discourse
 
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptxMan or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
Man or Manufactured_ Redefining Humanity Through Biopunk Narratives.pptx
 
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptxBIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
BIOCHEMISTRY-CARBOHYDRATE METABOLISM CHAPTER 2.pptx
 
Oppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and FilmOppenheimer Film Discussion for Philosophy and Film
Oppenheimer Film Discussion for Philosophy and Film
 
4.11.24 Mass Incarceration and the New Jim Crow.pptx
4.11.24 Mass Incarceration and the New Jim Crow.pptx4.11.24 Mass Incarceration and the New Jim Crow.pptx
4.11.24 Mass Incarceration and the New Jim Crow.pptx
 
Textual Evidence in Reading and Writing of SHS
Textual Evidence in Reading and Writing of SHSTextual Evidence in Reading and Writing of SHS
Textual Evidence in Reading and Writing of SHS
 
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
Blowin' in the Wind of Caste_ Bob Dylan's Song as a Catalyst for Social Justi...
 
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptxDecoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
Decoding the Tweet _ Practical Criticism in the Age of Hashtag.pptx
 
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptxDIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
DIFFERENT BASKETRY IN THE PHILIPPINES PPT.pptx
 
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
Team Lead Succeed – Helping you and your team achieve high-performance teamwo...
 
Multi Domain Alias In the Odoo 17 ERP Module
Multi Domain Alias In the Odoo 17 ERP ModuleMulti Domain Alias In the Odoo 17 ERP Module
Multi Domain Alias In the Odoo 17 ERP Module
 
ICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdfICS2208 Lecture6 Notes for SL spaces.pdf
ICS2208 Lecture6 Notes for SL spaces.pdf
 
How to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 DatabaseHow to Make a Duplicate of Your Odoo 17 Database
How to Make a Duplicate of Your Odoo 17 Database
 
Q-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITWQ-Factor General Quiz-7th April 2024, Quiz Club NITW
Q-Factor General Quiz-7th April 2024, Quiz Club NITW
 
Active Learning Strategies (in short ALS).pdf
Active Learning Strategies (in short ALS).pdfActive Learning Strategies (in short ALS).pdf
Active Learning Strategies (in short ALS).pdf
 
Grade Three -ELLNA-REVIEWER-ENGLISH.pptx
Grade Three -ELLNA-REVIEWER-ENGLISH.pptxGrade Three -ELLNA-REVIEWER-ENGLISH.pptx
Grade Three -ELLNA-REVIEWER-ENGLISH.pptx
 
Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4Daily Lesson Plan in Mathematics Quarter 4
Daily Lesson Plan in Mathematics Quarter 4
 
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
Visit to a blind student's school🧑‍🦯🧑‍🦯(community medicine)
 
31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...
31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...
31 ĐỀ THI THỬ VÀO LỚP 10 - TIẾNG ANH - FORM MỚI 2025 - 40 CÂU HỎI - BÙI VĂN V...
 

Qcon2011 functions rockpresentation_f_sharp

  • 1. Functions rock!Harnessing the Power of Functional Part II: Programming with F# TUTORIAL QCON 2011, London Prof. Dr. Michael Stal Michael.Stal@siemens.com
  • 2. Objectives of Presentation Introducing core concepts of Functional Programming Introducing F# as example Presentingthe benefits of combining OO and functional programming Illustrating the language in a pragmatic way preferring code over theory But not to cover every available aspect or to cover aspects in full detail Page 2
  • 3. Whatis Functional Programming? Praise the Lambda Calculus (which is almost 80 years old) and its successors (e.g., the typed ones) (Mathematical) Functions Are a means of decomposition Can be assigned to variables Can be passed as arguments to or returned from functions Can be anonymous (closures) Emphasize on Immutability: No side-effects of functions (referential transparency) Values instead of variables Page 3
  • 4. Functional ProgrammingLanguages … Are oftenhybrid such as Lisp/Clojure, F#, Scala Use Recursion instead of Iteration Can be strict (eager) or non-strict (lazy) Use mainly the Typed Lambda Calculus and thus support Pattern Matching Support concepts such as Monads, Continuations Integrate Comprehensions for collection types, Catamorphisms (fold), Anamorphisms (unfold) Page 4
  • 5. Preconception: Functional LanguagesareSlow Isnottrueanymoredue to: HighlyefficientVMslikethe CLR, JVM StructuralSharing, no naive copying TailCallOptimization: at least someVMs Veryefficient and powerfulLibraries Easy leveraging of Concurrency (e.g., because of immutablity) Page 5
  • 6. „Nowforsomethingcompletely different“ Introduction to F# 2.0 F# created by Don Syme at Microsoft Research, Cambridge, UK Started at 2002; team also closely associated with introduction of Generics to CLR F# combines Object Oriented Programming with Functional Programming Page 6 Don Syme, Source: msdn.microsoft.com/en-us/fsharp/default
  • 7.
  • 8. ML
  • 9.
  • 10. How to obtain F# Source code file may be compiled using fsc: fsc myExample.fs which creates an executable for the CLR You may run an interactive shell by using the following command line instead fsi In this case type the commands directly into the shell using ;; as delimiters You might use Visual Studio 2008 and install F# or Visual Studio 2010 (F# included!) You may use SharpDevelop and F# On Mac OS X, Linux: install Mono, then F# for Mac und Linux add MonoDevelop and the F# Add-In if you prefer an IDE Page 9 For instructions on how to install F# on Mac, Linux: http://functional-variations.net/
  • 11. Example: Using Visual Studio 2010 Page 10 Solution Explorer Editor Window F# Interactive
  • 12. F# in a Sandbox URL: http://tryfs.net/ Page 11
  • 13. F# Type System Basic types from the .NET CLI plus classes, interfaces, generics Function Types, Lambdas Tuples, Lists, Arrays Discriminated Unions Records and Structures Unit (equivalent to void in C++) Option (Monadic Type: Maybe Monad) Delegates Attributes Exceptions Page 12 bool, byte sbyte, int16, uint6, int, uint32, int64, uint64, char, nativeint, unativeint, string, decimal, unit, void, single, double
  • 14. let it be The let statement lets you define values Let‘s use the „REPL“ (actually not a REPL; F# is compiled on the fly) Page 13
  • 15. let for assigning values Values may be reassigned Mind the difference: the old values are not overwritten, but the identifiers refer to a new value! Page 14 let x = 5 // val x : int = 5 let x = x + 5 // val x : int = 10 let x = x - 9 // val x : int = 1
  • 16. let for function definition Using let for giving an anonymous function a name The function definition can also be written as: Page 15 let poly1 = fun x -> 2.0 * x * x - x + 1.0 // => valpoly1 float -> float poly1 1.5 // => val it : float = 4 A closure let poly1 x = 2.0 * x *x - x + 1.0 // => valpoly1 float -> float
  • 17. UsingClosures in F# Closuresrepresentfirst-classfunctionsthatcontainfree variables They bind free variables to theirdefinitioncontext Page 16 let a = 42 let g x f = f x printfn "%i" (g 12 (fun i -> a)) // => 42 // But we could also do something like: g 12 (printfn "%i") // => 12 binding Closure
  • 18. Specifying types is optional due to type inference Type inference allows the compiler to automatically defer the types But you can also specify types explicitly Page 17 let x : int = 12 let l : int List = [1; 2; 3] let twice (x: float) = 2.0 * x
  • 19. Special Types: unit unit represents an expression or function with no value Page 18 printfn"QCon 2011 rocks!";;  QCon2011 rocks! type is : valit : unit = () let printHello = printfn“Hello” type is : valprintHello: unit = ()
  • 20. Special Types: Option Option is a monadic type (MayBe-Monad) for expressions that either return nothing or a result Applicable to avoid dealing with alternative conditions Page 19 let div a b = if (b = 0) then None else Some(a/b) div 6 3 // => Some(2) div 6 0 // => None
  • 21. let for recursive functions defining a recursive function requires the keyword rec Page 20 let rec fib n = if (n <= 1) then 1 else fib(n-1) + fib(n-2) (* fib 1 => 1 fib 2 => 2 fib 3 => 3 fib 4 => 5 fib 5 => 8 *)
  • 22. Mutual Recursion defining mutual recursive functions Page 21 let rec f1 x = if (x <= 1) then 1 else f2(x) and f2 x = if (x % 2 = 0) then f1(x/2) else f1(x/2 - 1) printfn "%i" (f1 18) // => 1
  • 23. Currying and Partial Function Application F# supports partial function application: Page 22 > let mult x y = x * y;; valmult : int -> int -> int > let double x = mult 2 x;; val double : int -> int > double 3;; val it : int = 6 > double 4;; val it : int = 8 double is defined as partial application of mult with first param 2
  • 24. Lazy evaluations F# supports lazy evaluations Lazy means: the value is only calculated on demand Powerful usage for collections (see later) Page 23 let r = lazy ( let tmp = 2 * 21 printfn "Calculating" tmp ) printfn "%d" (r.Force()) // => Calculating // Forced evaluation 42
  • 25. Functions can be locally nested within functions Note: In F# like in all functional languages there are no statements but expressions Expressions always return values. The last value is used as the result of the expression like sum(a,b,c) / 3 in the example: Page 24 // using lightweight syntax: #light let avg (a,b,c) = let sum(a,b,c) = a + b + c sum(a,b,c) / 3 let d = avg(1,2,3) printfn “and the average is %i” d // => 2
  • 26. Operator Overloading in F# It is possible to define/overload operators Code Example: Page 25 let (*) a b = a + b let a = 2 * 7 // => a = 9 // may also be used in prefix notation: (*) 2 6 // => 8 // for unary operators: let (~-) n = 1 – n - 88 // => -87
  • 27. Exceptional F# raise used to raise exception of appropriate exception type try/with and try/(with/)finally both available Exceptions can also be raised with: failsWith “Wrong input“ Page 26 exceptionEvenArgument of int let printNumber n = if (n % 2 = 0) then raise (EvenArgument n) else printfn "%i" n try printNumber5 // ok printNumber4 // => exception EvenArgument 4 with EvenArgument x -> printfn "Number %i is even!" x
  • 28. The Pipeline Operator |> The pipeline |> operator is very powerful let (|>) x f = f x // applyfunction f to x There is also a <|operator (processing right to left) which is only seldomly used The pipeline operator unfolds its real power with all the sophisticated collection types Page 27 let x = sin 1.0 // or: let x = 1.0 |> sin
  • 29. Using Units of Measure F# allows to assign units of measure Compiler checks for compatibility Remember: Some big aeronautics and space projects failed due to such errors Page 28 [<Measure>] type m // meter [<Measure>] type s // second // let a = 5.0<m> + 7.3<s> =>compiler error let distance = 100.0<m> let time = 5.0<s> let speed = (distance/time) let distanceInAnHour = speed * 3600.0<s>
  • 30. Mutable F# Use the keyword mutable for defining real variables The F# API also supports ref. This denotes a record which contains a mutable element. Use ! to retrieve contained value and := to override Note: for some types mutable cousins exist Page 29 > let mutable a = 41;; val mutable a : int = 41 > a <- 42;; val it : unit = () > a;; val it : int = 42 > let i = ref(0);; val i : int ref = {contents = 0;} > i := !i + 42;; val it : unit = () > !i;; val it : int = 42
  • 31. Arrays According to MSDN/F#: Arrays are fixed-size, zero-based, mutable collections of consecutive data elements that are all of the same type Arrays can be created in several ways. Examples: Page 30 // specifying the elements let names = [| "Mick"; "Keith"; "Mark" |] // sequence expressions let squares = [| for i in 1..10 -> i * i |] // initialized array: 10 elems with 0 let ai : int array = Array.zeroCreate 10 // multidimensional 3 x 3 array let matrix : int array[,] = Array2D.zeroCreate 3 3
  • 32. Basic Array Operations Several basic operations are provided for arrays For example, operations to access parts of an array or operations to create new arrays Page 31 // get slice let subarr = squares.[3..5] // get element printfn "%d" ai.[2] // modify element ai.[2] <- 6
  • 33. Sophisticated Array operations There are also lots of more sophisticated operations for arrays that are also available for other kinds of collections Examples include fold, collect, concat, rev and more: Page 32 let a1 = [|1; 2; 3|] let a2 = [|4; 5; 6 |] let a12 = Array.concat [a1; a2] // new array! [| 1 .. 10 |] // array containing 1,2,3,..,10 |> Array.filter (fun elem -> elem % 2 = 0) // even // for numbers n but 8 put Some(n * n) into array: |> Array.choose (fun elem -> if (elem <> 8) then Some(elem*elem) else None) |> Array.rev// revert sort order |> printfn "%A" //=> [|100; 36; 16; 4|]
  • 34. Using Namespaces and Modules Using the .NET Framework Classes is straightforward You may import namespaces using open Namespaces are defined in F# with namespace, modules with module Namespaces mustn‘t define values Page 33 open System.Windows.Forms let form = new Form (Visible=true, Text="QCon 2011") let button = new Button(Text ="Click me") button.Click.Add (fun _ -> printfn "Hello, London!") form.Controls.Add(button) form.BackColor <- System.Drawing.Color.Azure Application.Run form
  • 35. Modules F# Modulescancontainvalues, typedefinitions, submodules Modulesarecompiled as classeswithstaticmembers Page 34 moduleMathModule letrechcf (a:bigint) (b:bigint) = if a = 0I then b elif (a < b) thenhcf a (b-a) elsehcf (a-b) b type Rational(a: bigint, b: bigint) = let n = hcf a b memberr.a = a / n memberr.b = b / n staticmember (+) r1 r2 = …
  • 36. Implicit Generics F# applies type inference for each definition If it cannot assign types it will treat the definition as a generic definition with type parameters In the example above the type parameter is 'a Let us instantiate the definition: Page 35 > let makeList a b = [a; b] => valmakeList : 'a -> 'a -> 'a list makeList 1 2 => valit : int list = [1; 2]
  • 37.
  • 38. Tuples Tuples are very convenient for various applications Page 37 let x = ( 1, 2) // val x : int * int = (1, 2) let a, b = x // val b : int = 2 // val a : int = 1 let ad = ("Adam", 7) // val ad : string * int = ("Adam", 7) let swap (a,b) = (b,a) // val swap : 'a * 'b -> 'b * 'a
  • 39. Sets sets are used for various problems Page 38 open System let s : Set<int> = Set(seq{ 1..7 }) let t = set[1;2;3] Console.WriteLine(s.Count) Console.WriteLine(s.MaximumElement) Console.WriteLine(s.IsProperSubsetOf(Set(seq{ 1..10 }))) Console.WriteLine(s.IsProperSupersetOf(t)) Console.WriteLine(s) let sl = Set.toList s // make a list
  • 40. Maps Maps (hash tables, dictionaries) are used as follows: Page 39 let m = Map.empty .Add("Syme", "F#") .Add("Stroustrup", "C++") .Add("Gosling", "Java") .Add("McCarthy", "Lisp") match m.TryFind("Syme") with | None -> printfn "not found" | Some(lng) -> printfn "%s" lng // F# Console.WriteLine(m.["McCarthy"]) // Lisp
  • 41. Land of Lists Lists are the core datatype of all functional languages F# provides excellent support for lists Page 40 let l = [] // empty list let l2 = "Hello" :: ", " :: l // add elements at the head let l3 = ["London"] let l4 = l2 @ l3 // concatenate two lists let l5 = l4 @ ["!";"!"] let l6 = List.rev l5 // reverse order printfn "%A" l5 => [“Hello”;”, “;”London”;”!”;”!”]
  • 42. And even more on Lists Several additional functions provided for lists In addition, List contains many static members Page 41 let l = [ 'a'; 'b'; 'c'; 'd' ] printfn "%c" l.Head // => a printfn "%A" l.Tail // => [‘b’;’c’;’d’] printfn "%d" l.Length // => 4 let lzip = List.zip [1; 2; 3] ['a';'b';'c'] printfn "%A" lzip // => [(1, 'a'); (2, 'b'); (3, 'c')] let arr = List.toArraylzip // make array
  • 43. Pattern Matching Pattern matching eases processing in functional languages It is applicable for all data types but is particularly valuable for collections Page 42 let rec addNumbers (l : 'int List) = match l with | [] -> 0 | head :: tail -> head + addNumbers tail let l = [1; 2; 3; 4; 5] let sum = addNumbers l printfn "%i" sum => 15
  • 44. Detour: General Pattern Matching Pattern matching allows to analyze arguments for their value or type Appears to be a Java/C# switch on stereoids, but is much more powerful, especially when dealing with collection types The :? operator defines a dynamic type test Note there are also operators for static upcast (e.g., 1 :> obj ) and dynamic downcast (e.g., shape :?> circle) in F# Page 43 let reportObject (x: obj) = match x with | :? string as s -> printfn"string '%s'" s | :? int as d -> printfn"integer '%d'" d | :? float as f -> println “float ‘%f’” f | _ -> printfn“unknown"
  • 45. Detour: General Pattern Matching using When clauses when allows to further check an argument during pattern matching Page 44 let i = -12 match i with | _ when i > 0 -> printfn "positive" | _ when i < 0 -> printfn "negative" | _ -> printfn "zero“
  • 46. Detour: The wildcard _ In F# _ serves as a wildcard character Always used when you like to ignore parts of an expression Another example: ignoring parameters Page 45 match groups with | // pattern matching 1 | _ :: rest -> findFSharpUGs rest | [] -> printfn "end of list" let apply f x = f x printfn "%i" (apply (fun _ -> 42) 12) // => 42
  • 47. Operations on Collections: map There are several operations for collections that reveal the power of functional programming. The most prominent example is map Page 46 let l = [1; 2; 3; 4; 5] let l2 = List.map (fun x -> x * x) l printfn "%A" l2 // => [1; 4; 9; 16; 25] Apply the function (1st param) to all arguments of the list (2nd param) and create a new list from the results
  • 48. Operations on Collections: filter With filter you can filter elements from a list Useful to create views on lists Page 47 let l = ["Martin"; "Erich"; "Kent"; "Gregor"; "Kevlin"] let view = l |> List.filter(fun elem-> elem.StartsWith("K")) printfn "%A" view // => [“Kent”; “Kevlin”] Put all those elements that fulfil the condition into the result list
  • 49. Operations on Collections: fold With foldand foldbackyou may iterate through a collection (from left to right respecitely from right to left) and apply a function Let me give you an example fold takes the current element in the collection it has iterated to, applies the specified function on the accumulator and this element, and passes the result to the next iteration as new accumulator This can be used , for instance, to add all numbers in the collection as depicted in the example Page 48 let l = [1 ; 2; 3; 4; 5 ] let sum a i = a + i let result = List.foldsum 0 l printfn "result is %i" result // => 15 collection function Intitial value for accumulator
  • 50. UsingPipeliningwithCollections = Power! Here the power of the pipeline operator can be leveraged Pipelining also improves readability Page 49 let l = [1; 2; 3; 4; 5] let l2 = l |> List.map (fun x -> x * x) |> List.rev printfn "%A" l2 // => [25; 16; 9; 4; 1] Take the list, apply the operation to all of Its elements, and revert the list
  • 51. List Comprehensions In functional programming recursion and comprehensions compensate for imperative loops Lists can be easily generated using comprehensions Sequences in F# are collections of typeIEnumerable They are subject to lazy evaluation! let s = seq { for i in 1 .. 10 do yield i + 1 } Page 50 // all values from 1 to 10 let l1 = [ 1 .. 10 ] // all values from 1 to 9 in steps of 2 let l2 = [ 1 .. 2 .. 9 ] // all squares for n from 1 upto10 let l3 = [for n in 1 .. 10 do yield n * n]
  • 52. Unfold on Sequences Unfold generates a sequence using a function (opposite of fold) (´State -> ´T * ´State option) -> ´State -> seq<´T> Take current state and return an option tuple with next element of sequence and next state The initial state value Generated sequence Page 51 let fibI = Seq.unfold( fun state -> Some(fst state + snd state, (snd state, fst state + snd state)) )(1I,1I) let tmp = fibI |> Seq.take100 for x in tmp do System.Console.WriteLine x
  • 53. Records Records are similar to tuples In records, however, fields are named Field names become accessors of the record type Page 52 type usergroup = { topic: string; members: string list } let fs_fans = { topic = "F#"; members = [ "Don"; "Michael"; "Ted"] } printfn"topic is %s " fs_fans.topic printfn "members: %A " fs_fans.members // => topic is F# // members: ["Don"; "Michael"; "Ted"]
  • 54. Cloning Records You can clone records and overwrite their fields partially using with Page 53 type person = { name : string; prefnum: int } let douglas = { name = "douglas";prefnum= 42 } let michael = { douglas with name = "michael"} printfn "%s %d" michael.name michael.preferred_num
  • 55. Records and Pattern Matching Alternatively you may use pattern matching for accessing and checking fields Page 54 type usergroup = { topic: string; members: string list } let cs_DE = {topic = "C#"; members = ["Tim"; "Tom; Pit" ]} let fs_FR = {topic = "F#"; members = [ "Henry"; "Marc"; "Bert" ]} let rec findFSharpUGs (groups: usergroup list) = match groups with | { topic = "F#"; members = m } :: rest -> printfn "%A" m findFSharpUGs rest | _ :: rest -> findFSharpUGs rest | [] -> printfn "end of list" findFSharpUGs[cs_DE; fs_FR]
  • 56. Discriminated Unions One of the core type constructs in F# Aggregates different structures The name after | is called a constructor or discriminator Page 55 type Content = string type BinTree = | Node of BinTree * BinTree | Leaf of Content // example usage: let bLeft = Node(Leaf("1.1"), Leaf("1.2")) let bRight = Leaf("2.1") let b = Node(bLeft, bRight)
  • 57. Discriminated Unions and Pattern Matching ... Best served with Pattern Matching Page 56 let rec treePrint b = match b with | Node(bl,br) -> printf "(" treePrintbl printf "|" treePrintbr printf ")" | Leaf(c) -> printf "[%s]" c treePrint b //=>(([1.1]|[1.2])|[2.1])
  • 58. Example: Functions as Types Functions are also types. Let‘s implement the Command pattern in F# Page 57 type Command = Command of (int -> int) let command1 = Command(fun i -> i + 1) let command2 = Command(fun i -> i * i) let command3 = Command(fun i -> i / 3) let rec exec commands = match commands with | [] -> printf "end" | Command(f) :: r -> let res = f 6 printfn "%i" res exec r // recursion on rest let cmdseq= [command1; command2; command3] exec cmdseq// => 7 <cr> 36 <cr> 2
  • 59. Detour: Acquiring and Disposing Resources withuse Theuseoperator in F# behavessimilar to using in C# Whenacquiring a resource, use will makesurethatthe Disposemethodiscalled (objecttypemustimplementIDisposable) Whenthescope of theobjectisleft, no matter how, theresource will getdeleted Page 58 let writeAText () = useotf = File.CreateText(@“QCON2011.txt") otf.WriteLine(“F# is fun!")
  • 60. Enums Enums in F# areexpressedsimilar to discriminatedunions Page 59 type Ratings = | Excellent = 10 | Good = 7 | Average = 5 | Fair = 3 | Bad = 1
  • 61. Mutual Recursive Types Types in F# can not refer to types defined in a later part You need to have a mutual recursive definition using and Page 60 type Element = | Content of string | Ref of Tree // Error: Tree not defined type Tree = | Node of Tree * Element * Tree | Leaf of Element type Element = | Content of string | Ref of Tree and Tree = | Node of Tree * Element * Tree | Leaf of Element
  • 62. Extend Pattern Matching with Active Patterns For extending pattern matching you may define yourown patterns This is done using active patterns as shown in the example: Page 61 type Coordinate(x : float, y : float) = member c.x = x member c.y = y member c.r= Math.Sqrt(c.x**2.0+c.y**2.0) member c.a= Math.Atan(c.y / c.x) let (|Polar|) (c : Coordinate) = (c.a, c.r) let printPolar c = match c with | Polar(a, r) -> printfn "a=%f r=%f" a r printPolar(new Coordinate(1.0,1.0))
  • 63. Another Example for Active Patterns We can even provide patterns for existing (.NET) types Page 62 let (|Int|Float|String|) (o : Object) = match o with | :? string -> String("42") | :? float -> Float(42.0) | :? int -> Int(42) let rec print42 (o : Object) = match o with | String(s) -> Console.WriteLine("String : {0}",s) | Float(f) -> Console.WriteLine("Float : {0}",f) | Int(i) -> Console.WriteLine("Int : {0}",i) print42 "universe" // => String : 42
  • 64. Partial Active Patterns Partial patterns return Options Page 63 let (|Even|_|) n = if (n % 2 = 0) // n mod 2 = 0 then Some(n) // yes => return Some(val) else None // no => return None let checkEven n = match n with | Even(m) -> printfn "even" | _ -> printfn "odd" checkEven 12 // “even” checkEven 13 // “odd”
  • 65. Keywordfunction For patternmatching an interestingshortexistsusingthekeywordfunction Page 64 // instead of: let rec combine2String sep s = match s with | [] -> "" | h :: t -> h.ToString() + sep + combine2String sep t printfn "%s" (combine2String " " ["Hello ";"QCon"]) // you may also use: let rec combine2String’ sep = function | [] -> "" | h :: t -> h.ToString() + sep + combine2String’ sep t printfn "%s" (combineToString’ " " ["Hello ";"QCon"])
  • 66. On the Road to OOP F# supports object-oriented programming The first step to OOP is assigning functionality to objects Page 65 type Name = { first: string; middle : char; last: string } with override x.ToString() = x.first + " " + x.middle.ToString() + " " + x.last member x.printName = printfn "%s“ (x.ToString()) let JFK : Name = { first = "John"; middle = 'F'; last = "Kennedy" } JFK.printName // => John F Kennedy
  • 67. Object Expressions We can also instantiate interfaces within a variable definition In the next slides we‘ll dive deeper into classes/interfaces in F# Page 66 open System open System.Collections.Generic let comparer = { new IComparer <string> with // sort by length! member x.Compare(s1, s2) = let s1Len = s1.Length let s2Len = s2.Length s1Len.CompareTo(s2Len) } let a = [|"Peter"; "Mike"; "Tim"|] Array.Sort(a, comparer) // arrays are mutable! printfn"%A" a // => [| "Tim“; "Mike"; "Peter"|]
  • 68. DefiningClasses in F# Classes in F# offerthesamecapabilities such as in C# For membersweneed to specify a instancename Page 67 type Circle (radius : float, center: float * float) = static let UnitCircle= Circle(1.0, (float 0, float 0)) member v.scale(k) = Circle(k * radius, center) member v.radius = radius member v.center = center static member unitCircle = UnitCircle override v.ToString() = "r = " + v.radius.ToString() + " and c = " + v.center.ToString() let c = Circle(2.0, (3.0,4.0)) System.Console.WriteLine c
  • 69. Explicit Fields letbindingsalwaysrequireinitialization Ifyou do notneed an initialization,useexplicitvaluesinstead! Theattribute[<DefaultValue>] isrequiredforvaluesthatshould will beinitialized to zero. For typeswithoutzeroinitializationwemustsetfields in theconstructor Page 68 type Book (author : string, title : string) = [<DefaultValue>] val mutable rating : float [<DefaultValue>] val mutable readers : int member b.rate(current : float) = b.readers <- b.readers + 1 b.rating <- (b.rating + current) / b.readers let fSharpBook = new Book (“Don Syme”, “Expert F#”) fSharpBook.readers <- 0 fSharpBook.rating <- 0.0
  • 70. Abstract Classes Abstract typesresp.classesmusthave an attributeAbstractClass Derivingfrom a baseclassrequirestheinheritkeyword Page 69 [<AbstractClass>] type Shape() = abstract draw: unit -> unit type Circle (radius : float, center: float * float) = inherit Shape() // all the other members default v.draw() = printfn "%s" (v.ToString()) Useoverrideforoverridingimplementations and defaultforoverriding an abstractmethod
  • 71. VisibilityAnnotations F# support private, public, internalvisibility Also applicable to modules Page 70 Thisishowyou canaddmore constructors type SpaceShip(name : string) = new() = new SpaceShip("NCC-1701") member private s.name = name member internals.speed = ref(0) member publics.call(msg : string) = printfn "Got message %s" msg member publics.accelerate() = if (!s.speed < 8) then s.speed := !s.speed + 1 member public s.stopEngines() = s.speed := 0 member s.id with get() = s.name // and set(id) = ... if it were mutable
  • 72. Default and Optional Parameters In F# 2.0 types, functions can have default and optional parameters In functions optional parameters have Option type! Page 71 open System type CoolProgrammingLanguage(?name : string, ?compile : bool) = let name = defaultArg name "F#" // default value let compile = true // optional parameter member x.Name = name member x.Compile = compile let fsharp = new CoolProgrammingLanguage() // returns F# and true: Console.WriteLine(fsharp.Name + " " + fsharp.Compile.ToString())
  • 73. Defining and Using Interfaces Interfaces aredefined as abstracttypeswithonlyabstractmembers Usingthem in a classrequirestheinterfacekeyword Page 72 type IDraw = abstract draw: unit -> unit type Line(p1 : float * float, p2: float * float) = member l.p1 = p1 member l.p2 = p2 interface IDraw with member l.draw() = let lineWeight = 2 // ........... printfn "done"
  • 74. ObjectExpressions and Interfaces Youmay also instantiate an interfacedirectly in a function Page 73 typeIDraw = abstractdraw: unit -> unit let point(p : float * float) = { newIDrawwith member x.draw() = printfn "drawing the line" } point(2.0, 3.0).draw() // => drawingtheline
  • 76. Continuations Continuationsbasicallyis „a function that receives the result of an expression after it’s been computed“ Page 75 // instead of writing let x = 3 let y = 4 let e1 = x * y let e2 = e1 + 1 // we pass the continuation as an argument to // a function that takes the result and continues the // evaluation. This is an inside-out approach: let cont_e cont = cont (x * y) let e3 = cont_e (fun i -> i + 1)
  • 77. ContinuationPassing Style (CPS) Butwhyshouldwecareabout CPS? Letususethefollowingexample Problem: this can‘t be subject to TCO (Tail Call Optimization) Works well forbalancedtreesbutnotforunbalancedones Solution: add an accumulator as extra argument Page 76 type Tree = | Node of string * Tree * Tree | Tip of string let rec size tree = match tree with | Tip _ -> 1 | Node(_,treeLeft,treeRight) -> size treeLeft + size treeRight
  • 78. CPS CaseStudy: Using an extra accumulator We just add an extra parameter and weassume (!) thetreeisskewed to the right (1 of 2 options) The call recursing over the right branch is a tail call, the left one isn‘t Thus, we still risk a stack overflow for trees that are more skewed to the left Page 77 let recsizeAcc acc tree = match tree with | Tip _ -> 1 + acc | Node(_,treeLeft,treeRight) -> let acc = sizeAcc acc treeLeft sizeAcc acc treeRight let size tree = sizeAcc 0 tree
  • 79. CPS CaseStudy: UsingContinuations Byusingcontinuations all branches will betail-calls Thestackoverflowproblem has beeneliminated Page 78 let recsizeCont tree cont = match tree with | Tip _ -> cont 1 | Node(_,treeLeft,treeRight) -> sizeConttreeLeft (fun leftSize -> sizeConttreeRight (fun rightSize -> cont (leftSize + rightSize))) let size tree = sizeCont tree (fun x -> x)
  • 80. Reactive, Asynchronous and Parallel F# Manythingswithin an applicationhappenasynchronously, such as Reading Web Pages Processing a GUI eventhandler Waitingfor I/O completion In addition, weshouldleveragethe power of Multicore CPUs Weneedlanguagesupportforreactive, asynchronous, and parallel processing Page 79 SocketforAthlon 64 X2 CPU Source: Wikipedia
  • 81. Using Mechanisms from the BCL In the .NET BCL (Base Class Library) there are already some mechanisms available such as threads and background workers We instantiate a BackgroundWorker from a pool of threads: let worker = new BackgroundWorker() We then pass a function with code to the worker it should execute: worker.DoWork.Add(fun args -> .....) In the next step we tell the worker which code to execute after its completion. An event will automtaically raised by the runtime . worker.RunWorkerCompleted.Add(fun args-> ...) Finally we start the worker‘s execution which raises an event to start DoWork: worker.RunWorkerAsync() Page 80
  • 82. Complete Example: Calculating the nth Fibonacci Page 81 let worker = new BackgroundWorker() let numIterations = 1000 worker.DoWork.Add(fun args -> let rec computeFibonacciresPrevPrevresPrev i = let res = resPrevPrev + resPrev if i = numIterations then args.Result <- box res // mutable access else computeFibonacciresPrev res (i+1) computeFibonacci 1 1 2) worker.RunWorkerCompleted.Add(fun args -> MessageBox.Show(sprintf "Result = %A" args.Result) |> ignore) worker.RunWorkerAsync()
  • 83. Async Example Microsoft.FSharp.Control.Async<'T> allows to define asynchronous workflows An Async instance will provide a result in the future (calling Start) let!, do!, return!, yield! imply asynchronous processing Page 82 let fetchAsync(url:string) = async { let req = WebRequest.Create(url) let! resp = req.AsyncGetResponse() let resp = req.GetResponse let stream = resp.GetResponseStream() let reader = new StreamReader(stream) let! html = reader.AsyncReadToEnd() printfn "Read %d characters for %s..." html.Lengthurl} Async.Start (fetchAsync(“http://fsharp.net”))
  • 84. Async - Under the Hood Internally, F# uses continuations. For example: will be implemented as Page 83 async { let req= WebRequest.Create("http://fsharp.net/") let! resp = req.AsyncGetResponse() let stream = resp.GetResponseStream() let reader = new StreamReader(stream) let! html = reader.AsyncReadToEnd() html } async.Delay(fun () -> let req = WebRequest.Create("http://fsharp.net/") async.Bind(req.AsyncGetResponse(), (fun resp -> let stream = resp.GetResponseStream() let reader = new StreamReader(stream) async.Bind(reader.AsyncReadToEnd(), (fun html -> async.Returnhtml)))
  • 85. An Example for Parallel Execution Page 84 open System.Threading open System let parallelArrayInit n f = let currentLine = ref -1 // reference let res = Array.zeroCreate n let rec loop () = let y = // locking with Interlocked Interlocked.Increment(&currentLine.contents) if y < n then res.[y] <- f y; loop() Async.Parallel[ for i in 1 .. Environment.ProcessorCount-> async{do loop()} ] |> Async.Ignore |> Async.RunSynchronously res let rec fib x=if x < 2 then 1 else fib(x-1)+fib(x-2) let it = parallelArrayInit 25 (fun x -> fib x) printfn "%A" it // => [|1; 1; 2; 3; 5; 8; 13; 21; 34; 55; 89; ... |]
  • 86. Agent-based Programming The class MailboxProcessor allows to implement agents which retrieve messages through their inbox Page 85 let counter = new MailboxProcessor<_>(fun inbox -> let rec loop n = async{ printfn "n = %d, waiting..." n let! msg = inbox.Receive() return! loop (n+msg) } loop 0) Counter.Start() // enter loop in asynchronous agent Counter.Post(42) // send message “42” to agent
  • 87. Summary F# pragmatically combines imperative (C# roots) with functional programming (OCaml roots) It runs on the CLR and thus offers interoperability with other CLI languages Excellent features for concurrency and asynchronous operation F# programs are compact and succinct causing less noise-to-signal ratio Support for Windows, Mac OS, Linux Availability on Visual Studio 2010 implies Microsoft is serious about functional languages Start Coding with F#! Page 86
  • 88. Books: My Recommendations D. Syme, A. Granicz, A. Cisternino: Expert F# 2.0 (Expert's Voice in F#), Apress; edition (June 7, 2010) C. Smith: Programming F#: A comprehensive guide for writing simple code to solve complex problems (Animal Guide), O'Reilly Media; edition (October 13, 2009) T. Petrícek, J. Skeet: Real World Functional Programming: With Examples in F# and C#, Manning Publications; edition (December 30, 2009) A lot of more books available Page 87
  • 89. F# Tools Lot of more available F# PowerPack: tools such as FsLex, FsYacc, (P)LINQ support, additional classes, SI Units for Measure, ... Amazing examples on http://code.msdn.microsoft.com/fsharpsamples xUnit.net for Unit Testing: http://xunit.codeplex.com/ or Nunit F# Web Tools: http://fswebtools.codeplex.com/ Page 88
  • 90. F# Links Interesting Links to F# information/sources Microsoft Research: http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/ Microsoft MSDN: http://msdn.microsoft.com/en-us/fsharp/default Don Symes Web Log: http://blogs.msdn.com/b/dsyme/ F# Community Samples: http://fsharpsamples.codeplex.com/ hubFS – The Place for F#: http://cs.hubfs.net/ Thomas Petricek: http://tomasp.net/ F# Blog by Jon Harrop: http://fsharpnews.blogspot.com/ TechED präsentation by Don Syme: http://blogs.msdn.com/b/dsyme/archive/2010/11/29/my-talk-at-teched-europe-2010-a-taste-of-f-today-and-future.aspx YouTube: http://www.youtube.com/watch?v=uyW4WZgwxJE Page 89
  • 91. Summary F# pragmatically combines imperative (C# roots) with functional programming (OCaml roots) It runs on the CLR and thus offers interoperability with other CLI languages Excellent features for concurrency and asynchronous operation F# programs are compact and succinct causing less noise-to-signal ratio Support for Windows, Mac OS, Linux Availability on Visual Studio 2010 implies Microsoft is serious about functional languages Start Coding with F#! Page 90
  • 92. Final Conclusions Functional Programmingisnotrestricted to academic researchanymore Big playersalreadyusetheparadigm such as Facebook, Twitter, Ericsson FP languageslikeClojure, Erlang, Scala, F# arenowreadyforthemainstream In addition, functionalfeatureshavebeenintegratedinto Java, C++, C#, Ruby, Smalltalk, .. CLR/JVM offerseveralbenefits: Interoperability Availability of richframeworklibraries Availability of powerfultools Availability of large communities No Big Bang approachrecommended. Start small, growbig Distributetheword and letthe force bewithyou Page 91