SlideShare a Scribd company logo
Functions rock!Harnessing the Power of Functional Part II: Programming with F#TUTORIALQCON 2011, LondonProf. Dr. Michael StalMichael.Stal@siemens.com
Objectives of PresentationIntroducing core concepts of Functional ProgrammingIntroducing F# as examplePresentingthe benefits of combining OO and functional programmingIllustrating the language in a pragmatic way preferring code over theoryBut not to cover every available aspect or to cover aspects in full  detailPage 2
Whatis Functional Programming?Praise the Lambda Calculus (which is almost 80 years old) and its successors  (e.g., the typed ones)(Mathematical) FunctionsAre a means of decompositionCan 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#, ScalaUse Recursion instead of IterationCan be strict (eager) or non-strict (lazy)Use  mainly the Typed Lambda Calculus and thus support Pattern MatchingSupport concepts such as Monads, ContinuationsIntegrate Comprehensions for collection types, Catamorphisms (fold), Anamorphisms (unfold)Page 4
Preconception: Functional LanguagesareSlowIsnottrueanymoredue to:HighlyefficientVMslikethe CLR, JVMStructuralSharing, no naive copyingTailCallOptimization: at least someVMsVeryefficient and powerfulLibrariesEasy leveraging of Concurrency (e.g., because of immutablity)Page 5
„Nowforsomethingcompletely different“ Introduction to F# 2.0F# created by Don Syme at Microsoft Research, Cambridge, UKStarted at 2002; team also closely associated with introduction of Generics to CLRF# combinesObject Oriented Programming withFunctional Programming Page 6Don Syme, Source: msdn.microsoft.com/en-us/fsharp/default
Core Properties of F#F# is compatible: runs on CLR/Mono, interoperability with other CLR languagesF# is simple and compact: a very small language core with a flat learning curveF# is succinct: More compact code, lower noise-to-signal ratio F# is high-level: Higher level of abstraction by combining OO with functional programmingF# is statically typed: type inference gives F#  the „look&feel“ of a dynamically typed languagePage 7F#‘s Roots: Haskell
ML
OCaml(similar core    language) C# (similar object model)A small Appetizer – taken from „Expert F#“!Page 8Functions/// Split a string into words at spaceslet splitAtSpaces (text: string) =text.Split' '  |> Array.toList/// Analyze a string for duplicate wordslet wordCount text =  let words = splitAtSpaces text  let wordSet = Set.ofList words  let numWords = words.Length  let numDups = words.Length - wordSet.Count  (numWords,numDups)/// Analyze a string for duplicate words and display the results.let showWordCount text =  let numWords,numDups = wordCount textprintfn"--> %d words in the text" numWordsprintfn"--> %d duplicate words" numDupslet main =   showWordCount "Hello, F# developer. As a developer you will have a lot of fun using F#"do main // => 15 words in the text <cr> 2 duplicate wordsType Inferenceno semicolonsImmutable valuesNo brackets!
How to obtain F#Source code file may be compiled using fsc:fsc myExample.fswhich creates an executable for the CLRYou may run an interactive shell by using the following command line insteadfsiIn this case type the commands directly into the shell using ;; as delimitersYou 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 Linuxadd MonoDevelop and the F# Add-In if you prefer an IDEPage 9For instructions on how to install F# on Mac, Linux:http://functional-variations.net/
Example: Using Visual Studio 2010Page 10SolutionExplorerEditor WindowF# Interactive
F# in a SandboxURL: http://tryfs.net/Page 11
F# Type SystemBasic types from the .NET CLI plus classes, interfaces, genericsFunction Types, LambdasTuples, Lists, ArraysDiscriminated UnionsRecords and StructuresUnit (equivalent to void in C++)Option (Monadic Type: Maybe Monad)DelegatesAttributesExceptionsPage 12bool, byte sbyte, int16, uint6,int, uint32, int64, uint64, char,nativeint, unativeint, string, decimal, unit, void, single,double
let it beThe let statement lets you define valuesLet‘s use the „REPL“ (actually not a REPL; F# is compiled on the fly)Page 13
let for  assigning valuesValues may be reassignedMind the difference: the old values are not overwritten, but the identifiers refer to a new value! Page 14let x = 5// val x : int = 5let x = x + 5// val x : int = 10let x = x - 9// val x : int = 1
let for function definitionUsing let for giving an anonymous function a nameThe function definition can also be written as:Page 15let poly1 = fun x -> 2.0 * x * x - x + 1.0// => valpoly1 float -> floatpoly1 1.5// => val it : float = 4A closurelet poly1 x = 2.0 * x *x - x + 1.0// => valpoly1 float -> float
UsingClosures in F#Closuresrepresentfirst-classfunctionsthatcontainfree variablesThey bind free variables to theirdefinitioncontextPage 16let a = 42let g x f = f x printfn "%i" (g 12 (fun i -> a)) // => 42// But we could also do something like:g 12 (printfn "%i") // => 12bindingClosure
Specifying types is optional due to type inferenceType inference allows the compiler to automatically defer the typesBut you can also specify types explicitly Page 17let x : int = 12let l : int List = [1; 2; 3]let twice (x: float) = 2.0 * x
Special Types: unitunit represents an expression or function with no valuePage 18printfn"QCon 2011 rocks!";; QCon2011 rocks!type is : valit : unit = ()let printHello = printfn“Hello” type is : valprintHello: unit = ()
Special Types: OptionOption is a monadic type (MayBe-Monad) for expressions that either return nothing or a resultApplicable to avoid dealing with alternative conditionsPage 19let div a b =    if (b = 0) then None    else Some(a/b)div 6 3 // => Some(2)div 6 0 // => None
let for recursive functionsdefining a recursive function requires the keyword recPage 20let 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 Recursiondefining mutual recursive functionsPage 21let 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 ApplicationF# 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 = 8double is defined as partial application ofmult with first param 2
Lazy evaluationsF# supports lazy evaluationsLazy means: the value is only calculated on demandPowerful usage for collections (see later)Page 23let r  = lazy              ( let tmp = 2 * 21printfn "Calculating"tmp             )printfn "%d" (r.Force()) // => Calculating//    Forced evaluation 42
Functions can be locally nested within functionsNote:In F# like in all functional languages there are no statements but expressionsExpressions 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: #lightlet avg (a,b,c) =    let sum(a,b,c) = a + b + c    sum(a,b,c) / 3let d = avg(1,2,3) printfn “and the average is %i” d // => 2
Operator Overloading in F#It is possible to define/overload operatorsCode Example: Page 25let (*) a b = a + blet 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 typetry/with and try/(with/)finally both availableExceptions can also be raised with: failsWith “Wrong input“Page 26exceptionEvenArgument of intlet printNumber n =    if (n % 2 = 0)         then raise (EvenArgument  n)        else printfn "%i" ntry printNumber5 // okprintNumber4 // => exception EvenArgument 4 withEvenArgument x ->printfn "Number %i is even!" x
The Pipeline Operator |>The pipeline |> operator is very powerfullet (|>) x f = f x // applyfunction f to xThere is also a <|operator (processing right to left)  which is only seldomly usedThe pipeline operator unfolds its real power with all the sophisticated collection typesPage 27let x = sin 1.0// or:let x = 1.0 |> sin
Using Units of MeasureF# allows to assign units of measure Compiler checks for compatibilityRemember: 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 errorlet 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 variablesThe F# API also supports ref. This denotes a record which contains a mutable element. Use ! to retrieve contained value and := to overrideNote: for some types mutable cousins existPage 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
ArraysAccording to MSDN/F#: Arrays are fixed-size, zero-based, mutable collections of consecutive data elements that are all of the same typeArrays can be created in several ways. Examples:Page 30// specifying the elementslet names = [| "Mick"; "Keith"; "Mark" |]// sequence expressionslet squares = [| for i in 1..10 -> i * i |]// initialized array: 10 elems with 0let ai : int array = Array.zeroCreate 10// multidimensional 3 x 3 arraylet matrix : int array[,] = Array2D.zeroCreate 3 3
Basic Array OperationsSeveral basic operations are provided for arraysFor example, operations to access parts of an array or operations to create new arraysPage 31// get slicelet subarr = squares.[3..5]// get element printfn "%d" ai.[2]// modify elementai.[2] <- 6
Sophisticated Array operationsThere are also lots of more sophisticated operations for arrays that are also available for other kinds of collectionsExamples include fold, collect, concat, rev and more:Page 32let 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 ModulesUsing the .NET Framework Classes is straightforward You may import namespaces using openNamespaces are defined in F# with namespace, modules with moduleNamespaces mustn‘t define valuesPage 33open System.Windows.Formslet 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.AzureApplication.Run form
ModulesF# Modulescancontainvalues, typedefinitions, submodulesModulesarecompiled as classeswithstaticmembersPage 34moduleMathModuleletrechcf (a:bigint) (b:bigint) = if a = 0I then belif (a < b) thenhcf a (b-a)elsehcf (a-b) btype Rational(a: bigint, b: bigint) =let n = hcf a bmemberr.a = a / n memberr.b = b / nstaticmember (+) r1 r2 = …
Implicit GenericsF# applies type inference for each definitionIf it cannot assign types it will treat the definition as a generic definition with type parametersIn the example above the type parameter is 'aLet us instantiate the definition:Page 35> let makeList a b = [a; b]=> valmakeList : 'a -> 'a -> 'a listmakeList 1 2=> valit : int list = [1; 2]
Explicit GenericsBut you can also specify the types implicitlyLikewise, we can specify the type on usagePage 36let makeListExp<'T> (a : 'T) (b : 'T) =      [a; b];;=> val makeListExp : 'T -> 'T -> 'T listmakeListExp<int> 1 2;;=> valit : int list = [1; 2]
TuplesTuples are very convenient for various applicationsPage 37let x = ( 1, 2)    // val x : int * int = (1, 2)let a, b = x    // val b : int = 2    // val a : int = 1let ad = ("Adam", 7)    // val ad : string * int = ("Adam", 7)let swap (a,b) = (b,a)    // val swap : 'a * 'b -> 'b * 'a
Setssets are used for various problemsPage 38open Systemlet 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
MapsMaps (hash tables, dictionaries) are used as follows: Page 39let 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 ListsLists are the core datatype of all functional languagesF# provides excellent support for listsPage 40let l = [] // empty listlet l2 = "Hello" :: ", " :: l // add elements at the head let l3 = ["London"]let l4 = l2 @ l3 // concatenate two listslet l5 = l4 @  ["!";"!"] let l6 = List.rev l5 // reverse orderprintfn "%A" l5=> [“Hello”;”, “;”London”;”!”;”!”]
And even more on ListsSeveral additional functions provided for listsIn addition, List contains many static membersPage 41let l = [ 'a'; 'b'; 'c'; 'd' ]printfn "%c" l.Head   // => aprintfn "%A" l.Tail   // => [‘b’;’c’;’d’]printfn "%d" l.Length // => 4let 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 MatchingPattern matching eases processing in functional languagesIt is applicable for all data types but is particularly valuable for collectionsPage 42let rec addNumbers (l : 'int List) =    match l with| [] -> 0    | head :: tail -> head + addNumbers taillet l = [1; 2; 3; 4; 5]let sum = addNumbers lprintfn "%i" sum=> 15
Detour: General Pattern Matching Pattern matching allows to analyze arguments for their value or typeAppears to be a Java/C# switch on stereoids, but is much more powerful, especially when dealing with collection typesThe :? operator defines a dynamic type testNote there are also operators for static upcast  (e.g., 1 :> obj ) and dynamic downcast  (e.g., shape :?> circle) in F#Page 43let 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 matchingPage 44let i = -12match i  with    | _ when i > 0 -> printfn "positive"    | _ when i < 0 -> printfn "negative"    | _ -> printfn "zero“
Detour: The wildcard _In F# _ serves as a wildcard characterAlways used when you like to ignore parts of an expressionAnother example: ignoring parametersPage 45match groups with    | // pattern matching 1| _ :: rest -> findFSharpUGs rest    | [] -> printfn "end of list"let apply f x = f xprintfn "%i" (apply (fun _ -> 42) 12)// => 42
Operations on Collections: mapThere are several operations for collections that reveal the power of functional programming. The most prominent example is map  Page 46let l = [1; 2; 3; 4; 5]let l2 = List.map (fun x -> x * x) lprintfn "%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: filterWith filter you can filter elements from a listUseful to create views on listsPage 47let 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: foldWith foldand foldbackyou may iterate through a collection (from left to right respecitely from right to left) and apply a functionLet me give you an examplefold 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 accumulatorThis can be used , for instance, to add all numbers in the collection as depicted in the examplePage 48let l = [1 ; 2; 3; 4; 5 ]let sum a i =  a + ilet result = List.foldsum 0 lprintfn "result is %i" result // => 15collectionfunctionIntitial value for accumulator
UsingPipeliningwithCollections = Power!Here the power of the pipeline operator can be leveragedPipelining also improves readabilityPage 49let l = [1; 2; 3; 4; 5]let l2 =      l |> List.map (fun x -> x * x) |> List.revprintfn "%A" l2 // => [25; 16; 9; 4; 1]Take the list, apply the operation to all ofIts elements, and revert the list
List ComprehensionsIn functional programming recursion and comprehensions compensate for imperative loopsLists can be easily generated using comprehensionsSequences in F# are collections of typeIEnumerableThey are subject to lazy evaluation!let s = seq { for i in 1 .. 10 do yield i + 1 }Page 50// all values from 1 to 10let l1 = [ 1 .. 10 ]// all values from 1 to 9 in steps of 2let l2 = [ 1 .. 2 .. 9 ]// all squares for n from 1 upto10 let l3  =  [for n in 1 .. 10 do yield  n * n]
Unfold on SequencesUnfold 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 stateThe initial state valueGenerated sequencePage 51let fibI = Seq.unfold( fun state ->      Some(fst state + snd state, (snd state, fst state           + snd state)) )(1I,1I)let tmp = fibI |> Seq.take100for x in tmp do System.Console.WriteLine x
RecordsRecords are similar to tuplesIn records, however, fields are namedField names become accessors of the record typePage 52type usergroup = { topic: string; members: string list }let fs_fans = { topic = "F#"; members =     [ "Don"; "Michael"; "Ted"] }printfn"topic is %s " fs_fans.topicprintfn "members: %A " fs_fans.members// => topic is F#//    members: ["Don"; "Michael"; "Ted"]
Cloning RecordsYou can clone records and overwrite their fields partially using withPage 53type 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 MatchingAlternatively you may use pattern matching for accessing and checking fieldsPage 54type 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" mfindFSharpUGs rest    | _ :: rest -> findFSharpUGs rest    | [] -> printfn "end of list"findFSharpUGs[cs_DE; fs_FR]
Discriminated UnionsOne of the core type constructs in F#Aggregates different structuresThe name after | is called a constructor or discriminatorPage 55type Content = stringtype 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 MatchingPage 56let rec treePrint b =match b with    | Node(bl,br) -> printf "(" treePrintblprintf "|"treePrintbrprintf ")"    | Leaf(c) -> printf "[%s]" ctreePrint b //=>(([1.1]|[1.2])|[2.1])
Example: Functions as TypesFunctions are also types. Let‘s implement the Command pattern in F#Page 57type 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 6printfn "%i" res                         exec r // recursion on restlet cmdseq= [command1; command2; command3]exec cmdseq// => 7 <cr> 36 <cr> 2
Detour: Acquiring and Disposing Resources withuseTheuseoperator in F# behavessimilar to using in C#Whenacquiring a resource, use will makesurethattheDisposemethodiscalled (objecttypemustimplementIDisposable)Whenthescope of theobjectisleft, no matter how, theresource will getdeletedPage 58let writeAText () =useotf = 		File.CreateText(@“QCON2011.txt")otf.WriteLine(“F# is fun!")
EnumsEnums in F# areexpressedsimilar to discriminatedunionsPage 59type Ratings =    | Excellent = 10    | Good = 7    | Average = 5    | Fair = 3    | Bad = 1
Mutual Recursive TypesTypes in F# can not refer to types defined in a later partYou need to have a mutual recursive definition using and Page 60type Element =    | Content of string    | Ref of Tree // Error: Tree not definedtype Tree =    | Node of Tree * Element * Tree    | Leaf of Element	type Element =    | Content of string    | Ref of Treeand Tree =    | Node of Tree * Element * Tree    | Leaf of Element
Extend Pattern Matching with Active PatternsFor extending pattern matching you may define yourown patternsThis is done using active patterns as shown in the example:Page 61type 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 rprintPolar(new Coordinate(1.0,1.0))
Another Example for Active PatternsWe can even provide patterns for existing (.NET) typesPage 62let (|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 PatternsPartial patterns return OptionsPage 63let (|Even|_|) n =     if (n % 2 = 0) // n mod 2 = 0    then Some(n) // yes => return Some(val)    else None // no => return Nonelet checkEven n =    match n with    | Even(m) -> printfn "even"    | _ -> printfn "odd"checkEven 12 // “even”checkEven 13 // “odd”
KeywordfunctionFor patternmatching an interestingshortexistsusingthekeywordfunctionPage 64// instead of:let rec combine2String sep s =    match  s with    | [] -> ""    | h :: t ->  h.ToString() +  sep + combine2String sep tprintfn "%s" (combine2String " " ["Hello ";"QCon"])// you may also use:let rec combine2String’ sep = function    | [] -> ""    | h :: t ->  h.ToString() +  sep + combine2String’ sep tprintfn "%s" (combineToString’ " " ["Hello ";"QCon"])
On the Road to OOPF# supports object-oriented programmingThe first step to OOP is assigning functionality to objectsPage 65type 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 ExpressionsWe can also instantiate interfaces within a variable definitionIn the next slides we‘ll dive deeper into classes/interfaces in F#Page 66open Systemopen System.Collections.Genericlet 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 instancenamePage 67type 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 = centerstatic member unitCircle = UnitCircleoverride 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 FieldsletbindingsalwaysrequireinitializationIfyou do notneed an initialization,useexplicitvaluesinstead!Theattribute[<DefaultValue>] isrequiredforvaluesthatshould will beinitialized to zero. For typeswithoutzeroinitializationwemustsetfields in theconstructorPage 68type Book (author : string, title : string) =[<DefaultValue>] val mutable rating : float[<DefaultValue>] val mutable readers : int    member b.rate(current : float) =b.readers <- b.readers + 1b.rating  <- (b.rating + current) / b.readerslet fSharpBook = new Book (“Don Syme”, “Expert F#”)fSharpBook.readers <- 0fSharpBook.rating <- 0.0
Abstract ClassesAbstract typesresp.classesmusthave an attributeAbstractClassDerivingfrom a baseclassrequirestheinheritkeywordPage 69[<AbstractClass>]type Shape() =    abstract draw: unit -> unittype Circle (radius : float, center: float * float) =    inherit Shape()    // all the other members default v.draw() = printfn "%s" (v.ToString())Useoverrideforoverridingimplementations anddefaultforoverriding an abstractmethod
VisibilityAnnotationsF# support private, public, internalvisibilityAlso applicable to modulesPage 70Thisishowyoucanaddmoreconstructorstype 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 := 0member s.id         with get() = s.name        // and set(id) =  ... if it were mutable
Default and Optional ParametersIn F# 2.0 types, functions can have default and optional parametersIn functions optional parameters have Option type!Page 71open Systemtype CoolProgrammingLanguage(?name : string, ?compile : bool) =let name = defaultArg name "F#" // default value    let compile = true // optional parameter    member x.Name = name    member x.Compile = compilelet fsharp = new CoolProgrammingLanguage()// returns F# and true:Console.WriteLine(fsharp.Name + " " + fsharp.Compile.ToString())
Defining and Using InterfacesInterfaces aredefined as abstracttypeswithonlyabstractmembersUsingthem in a classrequirestheinterfacekeywordPage 72type IDraw =    abstract draw: unit -> unittype Line(p1 : float * float, p2: float * float) =    member l.p1 = p1    member l.p2 = p2interface IDraw with        member l.draw() =             let lineWeight =  2            // ...........printfn "done"
ObjectExpressions and InterfacesYoumay also instantiate an interfacedirectly in a functionPage 73typeIDraw =abstractdraw: unit -> unitlet point(p : float * float) ={ newIDrawwith        member x.draw() = printfn "drawing the line" }point(2.0, 3.0).draw()// => drawingtheline
Page 74Advanced F#
ContinuationsContinuationsbasicallyis „a function that receives the result of an expression after it’s been computed“Page 75// instead of writinglet x = 3let y = 4let 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?LetususethefollowingexampleProblem: this can‘t be subject to TCO (Tail Call Optimization)Works well forbalancedtreesbutnotforunbalancedonesSolution: add an accumulator as extra argumentPage 76type Tree =	| Node of string * Tree * Tree	| Tip of stringlet rec size tree =	match tree with		| Tip _ -> 1		| Node(_,treeLeft,treeRight) ->			size treeLeft + size treeRight
CPS CaseStudy: Using an extra accumulatorWe just add an extra parameterand weassume (!) thetreeisskewed to the right (1 of 2 options)The call recursing over the right branch is a tail call, the left one isn‘tThus, we still risk a stack overflow for trees that are more skewed to the leftPage 77let recsizeAcc acc tree =	match tree with		| Tip _ -> 1 + acc		| Node(_,treeLeft,treeRight) ->			let acc = sizeAcc acc treeLeftsizeAcc acc treeRightlet size tree = sizeAcc 0 tree
CPS CaseStudy: UsingContinuationsByusingcontinuations all branches will betail-callsThestackoverflowproblem has beeneliminatedPage 78let 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 asReading Web PagesProcessing a GUI eventhandlerWaitingfor I/O completionIn addition, weshouldleveragethe power of Multicore CPUs Weneedlanguagesupportforreactive, asynchronous, and parallel processingPage 79SocketforAthlon 64 X2 CPUSource: Wikipedia
Using Mechanisms from the BCLIn the .NET BCL (Base Class Library) there are already some mechanisms available such as threads and background workersWe 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 81let worker = new BackgroundWorker()let numIterations = 1000worker.DoWork.Add(fun args ->    let rec computeFibonacciresPrevPrevresPrev i =        let res = resPrevPrev + resPrev	  if i = numIterations thenargs.Result <- box res //  mutable access        elsecomputeFibonacciresPrev res (i+1)computeFibonacci 1 1 2)worker.RunWorkerCompleted.Add(fun args ->MessageBox.Show(sprintf "Result = %A" args.Result) |> ignore)worker.RunWorkerAsync()
Async ExampleMicrosoft.FSharp.Control.Async<'T> allows to define asynchronous workflowsAn Async instance will provide a result in the future (calling Start)let!, do!, return!, yield! imply asynchronous processingPage 82let 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 HoodInternally, F# uses continuations. For example:will be implemented asPage 83async { 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 ExecutionPage 84open System.Threadingopen Systemlet parallelArrayInit n f =let currentLine = ref -1 // reference    let res = Array.zeroCreate n    let rec loop () =        let y = // locking with InterlockedInterlocked.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.RunSynchronouslyreslet 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 ProgrammingThe class MailboxProcessor allows to implement agents which retrieve messages through their inboxPage 85let 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 agentCounter.Post(42) // send message “42” to agent
SummaryF# pragmatically combines imperative (C# roots)  with functional programming (OCaml roots)It runs on the CLR and thus offers interoperability with other CLI languagesExcellent features for concurrency and asynchronous operationF# programs are compact and succinct causing less noise-to-signal ratioSupport for Windows, Mac OS, LinuxAvailability on Visual Studio 2010 implies Microsoft is serious about functional languagesStart Coding with F#!Page 86
Books: My RecommendationsD. 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 availablePage 87
F# Tools Lot of more availableF# PowerPack: tools such as FsLex, FsYacc, (P)LINQ support, additional classes, SI Units for Measure, ...Amazing examples on http://code.msdn.microsoft.com/fsharpsamplesxUnit.net for Unit Testing: http://xunit.codeplex.com/ or NunitF# Web Tools: http://fswebtools.codeplex.com/Page 88
F# LinksInteresting Links to F# information/sourcesMicrosoft Research: http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/Microsoft MSDN: http://msdn.microsoft.com/en-us/fsharp/defaultDon 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.aspxYouTube: http://www.youtube.com/watch?v=uyW4WZgwxJEPage 89
SummaryF# pragmatically combines imperative (C# roots)  with functional programming (OCaml roots)It runs on the CLR and thus offers interoperability with other CLI languagesExcellent features for concurrency and asynchronous operationF# programs are compact and succinct causing less noise-to-signal ratioSupport for Windows, Mac OS, LinuxAvailability on Visual Studio 2010 implies Microsoft is serious about functional languagesStart Coding with F#!Page 90

More Related Content

PPTX
Qcon2011 functions rockpresentation_scala
PPTX
Oop2010 Scala Presentation Stal
PPTX
Oop2011 actor presentation_stal
PPSX
DIWE - Programming with JavaScript
PPSX
Esoft Metro Campus - Certificate in java basics
PPSX
DIWE - Advanced PHP Concepts
PPSX
Esoft Metro Campus - Programming with C++
PPSX
Esoft Metro Campus - Certificate in c / c++ programming
Qcon2011 functions rockpresentation_scala
Oop2010 Scala Presentation Stal
Oop2011 actor presentation_stal
DIWE - Programming with JavaScript
Esoft Metro Campus - Certificate in java basics
DIWE - Advanced PHP Concepts
Esoft Metro Campus - Programming with C++
Esoft Metro Campus - Certificate in c / c++ programming

What's hot (19)

PPTX
C# in depth
PDF
Why Java Sucks and C# Rocks (Final)
PPTX
Oops presentation
PPSX
DIWE - Fundamentals of PHP
PPT
Javascript
PDF
Introduction to C++
PPT
C by balaguruswami - e.balagurusamy
PDF
Java 8 features
PDF
PDF
C# / Java Language Comparison
PPSX
DITEC - Programming with Java
PPT
ParaSail
PDF
Javaz. Functional design in Java 8.
PPT
Scala
PDF
Swift, swiftly
PPTX
Modern C++
PPSX
SRAVANByCPP
PDF
Introduction to Functional Programming with Scala
C# in depth
Why Java Sucks and C# Rocks (Final)
Oops presentation
DIWE - Fundamentals of PHP
Javascript
Introduction to C++
C by balaguruswami - e.balagurusamy
Java 8 features
C# / Java Language Comparison
DITEC - Programming with Java
ParaSail
Javaz. Functional design in Java 8.
Scala
Swift, swiftly
Modern C++
SRAVANByCPP
Introduction to Functional Programming with Scala
Ad

Viewers also liked (7)

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

Similar to Qcon2011 functions rockpresentation_f_sharp (20)

ODP
F# 101
PDF
F# and Reactive Programming for iOS
PPTX
Sharper tools with F#
PPTX
Functional programming with FSharp
PPT
F# and the DLR
PDF
Functional Programming in F#
PDF
Functional programming with F#
PPTX
F# and functional programming
PPTX
Fsharp shdh 40 lightning talk
PPTX
What The F#
PPTX
Functional Programming Fundamentals
PPTX
Teaching F#
PPTX
Introduction to F#
PPTX
F# Presentation
PDF
Fsharp tutorial
PPTX
London F-Sharp User Group : Don Syme on F# - 09/09/2010
PPTX
F# intro
DOCX
In the Notes on Programming Language Syntax page, an example par.docx
PPTX
What the math geeks don't want you to know about F#
PPTX
Tech for devs, F#
F# 101
F# and Reactive Programming for iOS
Sharper tools with F#
Functional programming with FSharp
F# and the DLR
Functional Programming in F#
Functional programming with F#
F# and functional programming
Fsharp shdh 40 lightning talk
What The F#
Functional Programming Fundamentals
Teaching F#
Introduction to F#
F# Presentation
Fsharp tutorial
London F-Sharp User Group : Don Syme on F# - 09/09/2010
F# intro
In the Notes on Programming Language Syntax page, an example par.docx
What the math geeks don't want you to know about F#
Tech for devs, F#

Recently uploaded (20)

PDF
01-Introduction-to-Information-Management.pdf
PDF
Microbial disease of the cardiovascular and lymphatic systems
PDF
O7-L3 Supply Chain Operations - ICLT Program
PDF
Pre independence Education in Inndia.pdf
PDF
Basic Mud Logging Guide for educational purpose
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
PPTX
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
PDF
RMMM.pdf make it easy to upload and study
PDF
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
PPTX
Week 4 Term 3 Study Techniques revisited.pptx
PPTX
master seminar digital applications in india
PPTX
Microbial diseases, their pathogenesis and prophylaxis
PPTX
Pharma ospi slides which help in ospi learning
PDF
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
PPTX
Renaissance Architecture: A Journey from Faith to Humanism
PDF
Supply Chain Operations Speaking Notes -ICLT Program
PPTX
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
PDF
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
PDF
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
PDF
O5-L3 Freight Transport Ops (International) V1.pdf
01-Introduction-to-Information-Management.pdf
Microbial disease of the cardiovascular and lymphatic systems
O7-L3 Supply Chain Operations - ICLT Program
Pre independence Education in Inndia.pdf
Basic Mud Logging Guide for educational purpose
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
RMMM.pdf make it easy to upload and study
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
Week 4 Term 3 Study Techniques revisited.pptx
master seminar digital applications in india
Microbial diseases, their pathogenesis and prophylaxis
Pharma ospi slides which help in ospi learning
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
Renaissance Architecture: A Journey from Faith to Humanism
Supply Chain Operations Speaking Notes -ICLT Program
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
O5-L3 Freight Transport Ops (International) V1.pdf

Qcon2011 functions rockpresentation_f_sharp

  • 1. Functions rock!Harnessing the Power of Functional Part II: Programming with F#TUTORIALQCON 2011, LondonProf. Dr. Michael StalMichael.Stal@siemens.com
  • 2. Objectives of PresentationIntroducing core concepts of Functional ProgrammingIntroducing F# as examplePresentingthe benefits of combining OO and functional programmingIllustrating the language in a pragmatic way preferring code over theoryBut not to cover every available aspect or to cover aspects in full detailPage 2
  • 3. Whatis Functional Programming?Praise the Lambda Calculus (which is almost 80 years old) and its successors (e.g., the typed ones)(Mathematical) FunctionsAre a means of decompositionCan 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#, ScalaUse Recursion instead of IterationCan be strict (eager) or non-strict (lazy)Use mainly the Typed Lambda Calculus and thus support Pattern MatchingSupport concepts such as Monads, ContinuationsIntegrate Comprehensions for collection types, Catamorphisms (fold), Anamorphisms (unfold)Page 4
  • 5. Preconception: Functional LanguagesareSlowIsnottrueanymoredue to:HighlyefficientVMslikethe CLR, JVMStructuralSharing, no naive copyingTailCallOptimization: at least someVMsVeryefficient and powerfulLibrariesEasy leveraging of Concurrency (e.g., because of immutablity)Page 5
  • 6. „Nowforsomethingcompletely different“ Introduction to F# 2.0F# created by Don Syme at Microsoft Research, Cambridge, UKStarted at 2002; team also closely associated with introduction of Generics to CLRF# combinesObject Oriented Programming withFunctional Programming Page 6Don Syme, Source: msdn.microsoft.com/en-us/fsharp/default
  • 7. Core Properties of F#F# is compatible: runs on CLR/Mono, interoperability with other CLR languagesF# is simple and compact: a very small language core with a flat learning curveF# is succinct: More compact code, lower noise-to-signal ratio F# is high-level: Higher level of abstraction by combining OO with functional programmingF# is statically typed: type inference gives F# the „look&feel“ of a dynamically typed languagePage 7F#‘s Roots: Haskell
  • 8. ML
  • 9. OCaml(similar core language) C# (similar object model)A small Appetizer – taken from „Expert F#“!Page 8Functions/// Split a string into words at spaceslet splitAtSpaces (text: string) =text.Split' ' |> Array.toList/// Analyze a string for duplicate wordslet wordCount text = let words = splitAtSpaces text let wordSet = Set.ofList words let numWords = words.Length let numDups = words.Length - wordSet.Count (numWords,numDups)/// Analyze a string for duplicate words and display the results.let showWordCount text = let numWords,numDups = wordCount textprintfn"--> %d words in the text" numWordsprintfn"--> %d duplicate words" numDupslet main = showWordCount "Hello, F# developer. As a developer you will have a lot of fun using F#"do main // => 15 words in the text <cr> 2 duplicate wordsType Inferenceno semicolonsImmutable valuesNo brackets!
  • 10. How to obtain F#Source code file may be compiled using fsc:fsc myExample.fswhich creates an executable for the CLRYou may run an interactive shell by using the following command line insteadfsiIn this case type the commands directly into the shell using ;; as delimitersYou 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 Linuxadd MonoDevelop and the F# Add-In if you prefer an IDEPage 9For instructions on how to install F# on Mac, Linux:http://functional-variations.net/
  • 11. Example: Using Visual Studio 2010Page 10SolutionExplorerEditor WindowF# Interactive
  • 12. F# in a SandboxURL: http://tryfs.net/Page 11
  • 13. F# Type SystemBasic types from the .NET CLI plus classes, interfaces, genericsFunction Types, LambdasTuples, Lists, ArraysDiscriminated UnionsRecords and StructuresUnit (equivalent to void in C++)Option (Monadic Type: Maybe Monad)DelegatesAttributesExceptionsPage 12bool, byte sbyte, int16, uint6,int, uint32, int64, uint64, char,nativeint, unativeint, string, decimal, unit, void, single,double
  • 14. let it beThe let statement lets you define valuesLet‘s use the „REPL“ (actually not a REPL; F# is compiled on the fly)Page 13
  • 15. let for assigning valuesValues may be reassignedMind the difference: the old values are not overwritten, but the identifiers refer to a new value! Page 14let x = 5// val x : int = 5let x = x + 5// val x : int = 10let x = x - 9// val x : int = 1
  • 16. let for function definitionUsing let for giving an anonymous function a nameThe function definition can also be written as:Page 15let poly1 = fun x -> 2.0 * x * x - x + 1.0// => valpoly1 float -> floatpoly1 1.5// => val it : float = 4A closurelet poly1 x = 2.0 * x *x - x + 1.0// => valpoly1 float -> float
  • 17. UsingClosures in F#Closuresrepresentfirst-classfunctionsthatcontainfree variablesThey bind free variables to theirdefinitioncontextPage 16let a = 42let g x f = f x printfn "%i" (g 12 (fun i -> a)) // => 42// But we could also do something like:g 12 (printfn "%i") // => 12bindingClosure
  • 18. Specifying types is optional due to type inferenceType inference allows the compiler to automatically defer the typesBut you can also specify types explicitly Page 17let x : int = 12let l : int List = [1; 2; 3]let twice (x: float) = 2.0 * x
  • 19. Special Types: unitunit represents an expression or function with no valuePage 18printfn"QCon 2011 rocks!";; QCon2011 rocks!type is : valit : unit = ()let printHello = printfn“Hello” type is : valprintHello: unit = ()
  • 20. Special Types: OptionOption is a monadic type (MayBe-Monad) for expressions that either return nothing or a resultApplicable to avoid dealing with alternative conditionsPage 19let 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 functionsdefining a recursive function requires the keyword recPage 20let 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 Recursiondefining mutual recursive functionsPage 21let 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 ApplicationF# 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 = 8double is defined as partial application ofmult with first param 2
  • 24. Lazy evaluationsF# supports lazy evaluationsLazy means: the value is only calculated on demandPowerful usage for collections (see later)Page 23let r = lazy ( let tmp = 2 * 21printfn "Calculating"tmp )printfn "%d" (r.Force()) // => Calculating// Forced evaluation 42
  • 25. Functions can be locally nested within functionsNote:In F# like in all functional languages there are no statements but expressionsExpressions 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: #lightlet avg (a,b,c) = let sum(a,b,c) = a + b + c sum(a,b,c) / 3let d = avg(1,2,3) printfn “and the average is %i” d // => 2
  • 26. Operator Overloading in F#It is possible to define/overload operatorsCode Example: Page 25let (*) a b = a + blet 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 typetry/with and try/(with/)finally both availableExceptions can also be raised with: failsWith “Wrong input“Page 26exceptionEvenArgument of intlet printNumber n = if (n % 2 = 0) then raise (EvenArgument n) else printfn "%i" ntry printNumber5 // okprintNumber4 // => exception EvenArgument 4 withEvenArgument x ->printfn "Number %i is even!" x
  • 28. The Pipeline Operator |>The pipeline |> operator is very powerfullet (|>) x f = f x // applyfunction f to xThere is also a <|operator (processing right to left) which is only seldomly usedThe pipeline operator unfolds its real power with all the sophisticated collection typesPage 27let x = sin 1.0// or:let x = 1.0 |> sin
  • 29. Using Units of MeasureF# allows to assign units of measure Compiler checks for compatibilityRemember: 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 errorlet 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 variablesThe F# API also supports ref. This denotes a record which contains a mutable element. Use ! to retrieve contained value and := to overrideNote: for some types mutable cousins existPage 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. ArraysAccording to MSDN/F#: Arrays are fixed-size, zero-based, mutable collections of consecutive data elements that are all of the same typeArrays can be created in several ways. Examples:Page 30// specifying the elementslet names = [| "Mick"; "Keith"; "Mark" |]// sequence expressionslet squares = [| for i in 1..10 -> i * i |]// initialized array: 10 elems with 0let ai : int array = Array.zeroCreate 10// multidimensional 3 x 3 arraylet matrix : int array[,] = Array2D.zeroCreate 3 3
  • 32. Basic Array OperationsSeveral basic operations are provided for arraysFor example, operations to access parts of an array or operations to create new arraysPage 31// get slicelet subarr = squares.[3..5]// get element printfn "%d" ai.[2]// modify elementai.[2] <- 6
  • 33. Sophisticated Array operationsThere are also lots of more sophisticated operations for arrays that are also available for other kinds of collectionsExamples include fold, collect, concat, rev and more:Page 32let 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 ModulesUsing the .NET Framework Classes is straightforward You may import namespaces using openNamespaces are defined in F# with namespace, modules with moduleNamespaces mustn‘t define valuesPage 33open System.Windows.Formslet 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.AzureApplication.Run form
  • 35. ModulesF# Modulescancontainvalues, typedefinitions, submodulesModulesarecompiled as classeswithstaticmembersPage 34moduleMathModuleletrechcf (a:bigint) (b:bigint) = if a = 0I then belif (a < b) thenhcf a (b-a)elsehcf (a-b) btype Rational(a: bigint, b: bigint) =let n = hcf a bmemberr.a = a / n memberr.b = b / nstaticmember (+) r1 r2 = …
  • 36. Implicit GenericsF# applies type inference for each definitionIf it cannot assign types it will treat the definition as a generic definition with type parametersIn the example above the type parameter is 'aLet us instantiate the definition:Page 35> let makeList a b = [a; b]=> valmakeList : 'a -> 'a -> 'a listmakeList 1 2=> valit : int list = [1; 2]
  • 37. Explicit GenericsBut you can also specify the types implicitlyLikewise, we can specify the type on usagePage 36let makeListExp<'T> (a : 'T) (b : 'T) = [a; b];;=> val makeListExp : 'T -> 'T -> 'T listmakeListExp<int> 1 2;;=> valit : int list = [1; 2]
  • 38. TuplesTuples are very convenient for various applicationsPage 37let x = ( 1, 2) // val x : int * int = (1, 2)let a, b = x // val b : int = 2 // val a : int = 1let ad = ("Adam", 7) // val ad : string * int = ("Adam", 7)let swap (a,b) = (b,a) // val swap : 'a * 'b -> 'b * 'a
  • 39. Setssets are used for various problemsPage 38open Systemlet 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. MapsMaps (hash tables, dictionaries) are used as follows: Page 39let 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 ListsLists are the core datatype of all functional languagesF# provides excellent support for listsPage 40let l = [] // empty listlet l2 = "Hello" :: ", " :: l // add elements at the head let l3 = ["London"]let l4 = l2 @ l3 // concatenate two listslet l5 = l4 @ ["!";"!"] let l6 = List.rev l5 // reverse orderprintfn "%A" l5=> [“Hello”;”, “;”London”;”!”;”!”]
  • 42. And even more on ListsSeveral additional functions provided for listsIn addition, List contains many static membersPage 41let l = [ 'a'; 'b'; 'c'; 'd' ]printfn "%c" l.Head // => aprintfn "%A" l.Tail // => [‘b’;’c’;’d’]printfn "%d" l.Length // => 4let 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 MatchingPattern matching eases processing in functional languagesIt is applicable for all data types but is particularly valuable for collectionsPage 42let rec addNumbers (l : 'int List) = match l with| [] -> 0 | head :: tail -> head + addNumbers taillet l = [1; 2; 3; 4; 5]let sum = addNumbers lprintfn "%i" sum=> 15
  • 44. Detour: General Pattern Matching Pattern matching allows to analyze arguments for their value or typeAppears to be a Java/C# switch on stereoids, but is much more powerful, especially when dealing with collection typesThe :? operator defines a dynamic type testNote there are also operators for static upcast (e.g., 1 :> obj ) and dynamic downcast (e.g., shape :?> circle) in F#Page 43let 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 matchingPage 44let i = -12match i with | _ when i > 0 -> printfn "positive" | _ when i < 0 -> printfn "negative" | _ -> printfn "zero“
  • 46. Detour: The wildcard _In F# _ serves as a wildcard characterAlways used when you like to ignore parts of an expressionAnother example: ignoring parametersPage 45match groups with | // pattern matching 1| _ :: rest -> findFSharpUGs rest | [] -> printfn "end of list"let apply f x = f xprintfn "%i" (apply (fun _ -> 42) 12)// => 42
  • 47. Operations on Collections: mapThere are several operations for collections that reveal the power of functional programming. The most prominent example is map Page 46let l = [1; 2; 3; 4; 5]let l2 = List.map (fun x -> x * x) lprintfn "%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: filterWith filter you can filter elements from a listUseful to create views on listsPage 47let 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: foldWith foldand foldbackyou may iterate through a collection (from left to right respecitely from right to left) and apply a functionLet me give you an examplefold 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 accumulatorThis can be used , for instance, to add all numbers in the collection as depicted in the examplePage 48let l = [1 ; 2; 3; 4; 5 ]let sum a i = a + ilet result = List.foldsum 0 lprintfn "result is %i" result // => 15collectionfunctionIntitial value for accumulator
  • 50. UsingPipeliningwithCollections = Power!Here the power of the pipeline operator can be leveragedPipelining also improves readabilityPage 49let l = [1; 2; 3; 4; 5]let l2 = l |> List.map (fun x -> x * x) |> List.revprintfn "%A" l2 // => [25; 16; 9; 4; 1]Take the list, apply the operation to all ofIts elements, and revert the list
  • 51. List ComprehensionsIn functional programming recursion and comprehensions compensate for imperative loopsLists can be easily generated using comprehensionsSequences in F# are collections of typeIEnumerableThey are subject to lazy evaluation!let s = seq { for i in 1 .. 10 do yield i + 1 }Page 50// all values from 1 to 10let l1 = [ 1 .. 10 ]// all values from 1 to 9 in steps of 2let 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 SequencesUnfold 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 stateThe initial state valueGenerated sequencePage 51let fibI = Seq.unfold( fun state -> Some(fst state + snd state, (snd state, fst state + snd state)) )(1I,1I)let tmp = fibI |> Seq.take100for x in tmp do System.Console.WriteLine x
  • 53. RecordsRecords are similar to tuplesIn records, however, fields are namedField names become accessors of the record typePage 52type usergroup = { topic: string; members: string list }let fs_fans = { topic = "F#"; members = [ "Don"; "Michael"; "Ted"] }printfn"topic is %s " fs_fans.topicprintfn "members: %A " fs_fans.members// => topic is F#// members: ["Don"; "Michael"; "Ted"]
  • 54. Cloning RecordsYou can clone records and overwrite their fields partially using withPage 53type 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 MatchingAlternatively you may use pattern matching for accessing and checking fieldsPage 54type 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" mfindFSharpUGs rest | _ :: rest -> findFSharpUGs rest | [] -> printfn "end of list"findFSharpUGs[cs_DE; fs_FR]
  • 56. Discriminated UnionsOne of the core type constructs in F#Aggregates different structuresThe name after | is called a constructor or discriminatorPage 55type Content = stringtype 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 MatchingPage 56let rec treePrint b =match b with | Node(bl,br) -> printf "(" treePrintblprintf "|"treePrintbrprintf ")" | Leaf(c) -> printf "[%s]" ctreePrint b //=>(([1.1]|[1.2])|[2.1])
  • 58. Example: Functions as TypesFunctions are also types. Let‘s implement the Command pattern in F#Page 57type 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 6printfn "%i" res exec r // recursion on restlet cmdseq= [command1; command2; command3]exec cmdseq// => 7 <cr> 36 <cr> 2
  • 59. Detour: Acquiring and Disposing Resources withuseTheuseoperator in F# behavessimilar to using in C#Whenacquiring a resource, use will makesurethattheDisposemethodiscalled (objecttypemustimplementIDisposable)Whenthescope of theobjectisleft, no matter how, theresource will getdeletedPage 58let writeAText () =useotf = File.CreateText(@“QCON2011.txt")otf.WriteLine(“F# is fun!")
  • 60. EnumsEnums in F# areexpressedsimilar to discriminatedunionsPage 59type Ratings = | Excellent = 10 | Good = 7 | Average = 5 | Fair = 3 | Bad = 1
  • 61. Mutual Recursive TypesTypes in F# can not refer to types defined in a later partYou need to have a mutual recursive definition using and Page 60type Element = | Content of string | Ref of Tree // Error: Tree not definedtype Tree = | Node of Tree * Element * Tree | Leaf of Element type Element = | Content of string | Ref of Treeand Tree = | Node of Tree * Element * Tree | Leaf of Element
  • 62. Extend Pattern Matching with Active PatternsFor extending pattern matching you may define yourown patternsThis is done using active patterns as shown in the example:Page 61type 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 rprintPolar(new Coordinate(1.0,1.0))
  • 63. Another Example for Active PatternsWe can even provide patterns for existing (.NET) typesPage 62let (|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 PatternsPartial patterns return OptionsPage 63let (|Even|_|) n = if (n % 2 = 0) // n mod 2 = 0 then Some(n) // yes => return Some(val) else None // no => return Nonelet checkEven n = match n with | Even(m) -> printfn "even" | _ -> printfn "odd"checkEven 12 // “even”checkEven 13 // “odd”
  • 65. KeywordfunctionFor patternmatching an interestingshortexistsusingthekeywordfunctionPage 64// instead of:let rec combine2String sep s = match s with | [] -> "" | h :: t -> h.ToString() + sep + combine2String sep tprintfn "%s" (combine2String " " ["Hello ";"QCon"])// you may also use:let rec combine2String’ sep = function | [] -> "" | h :: t -> h.ToString() + sep + combine2String’ sep tprintfn "%s" (combineToString’ " " ["Hello ";"QCon"])
  • 66. On the Road to OOPF# supports object-oriented programmingThe first step to OOP is assigning functionality to objectsPage 65type 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 ExpressionsWe can also instantiate interfaces within a variable definitionIn the next slides we‘ll dive deeper into classes/interfaces in F#Page 66open Systemopen System.Collections.Genericlet 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 instancenamePage 67type 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 = centerstatic member unitCircle = UnitCircleoverride 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 FieldsletbindingsalwaysrequireinitializationIfyou do notneed an initialization,useexplicitvaluesinstead!Theattribute[<DefaultValue>] isrequiredforvaluesthatshould will beinitialized to zero. For typeswithoutzeroinitializationwemustsetfields in theconstructorPage 68type Book (author : string, title : string) =[<DefaultValue>] val mutable rating : float[<DefaultValue>] val mutable readers : int member b.rate(current : float) =b.readers <- b.readers + 1b.rating <- (b.rating + current) / b.readerslet fSharpBook = new Book (“Don Syme”, “Expert F#”)fSharpBook.readers <- 0fSharpBook.rating <- 0.0
  • 70. Abstract ClassesAbstract typesresp.classesmusthave an attributeAbstractClassDerivingfrom a baseclassrequirestheinheritkeywordPage 69[<AbstractClass>]type Shape() = abstract draw: unit -> unittype Circle (radius : float, center: float * float) = inherit Shape() // all the other members default v.draw() = printfn "%s" (v.ToString())Useoverrideforoverridingimplementations anddefaultforoverriding an abstractmethod
  • 71. VisibilityAnnotationsF# support private, public, internalvisibilityAlso applicable to modulesPage 70Thisishowyoucanaddmoreconstructorstype 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 := 0member s.id with get() = s.name // and set(id) = ... if it were mutable
  • 72. Default and Optional ParametersIn F# 2.0 types, functions can have default and optional parametersIn functions optional parameters have Option type!Page 71open Systemtype CoolProgrammingLanguage(?name : string, ?compile : bool) =let name = defaultArg name "F#" // default value let compile = true // optional parameter member x.Name = name member x.Compile = compilelet fsharp = new CoolProgrammingLanguage()// returns F# and true:Console.WriteLine(fsharp.Name + " " + fsharp.Compile.ToString())
  • 73. Defining and Using InterfacesInterfaces aredefined as abstracttypeswithonlyabstractmembersUsingthem in a classrequirestheinterfacekeywordPage 72type IDraw = abstract draw: unit -> unittype Line(p1 : float * float, p2: float * float) = member l.p1 = p1 member l.p2 = p2interface IDraw with member l.draw() = let lineWeight = 2 // ...........printfn "done"
  • 74. ObjectExpressions and InterfacesYoumay also instantiate an interfacedirectly in a functionPage 73typeIDraw =abstractdraw: unit -> unitlet point(p : float * float) ={ newIDrawwith member x.draw() = printfn "drawing the line" }point(2.0, 3.0).draw()// => drawingtheline
  • 76. ContinuationsContinuationsbasicallyis „a function that receives the result of an expression after it’s been computed“Page 75// instead of writinglet x = 3let y = 4let 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?LetususethefollowingexampleProblem: this can‘t be subject to TCO (Tail Call Optimization)Works well forbalancedtreesbutnotforunbalancedonesSolution: add an accumulator as extra argumentPage 76type Tree = | Node of string * Tree * Tree | Tip of stringlet rec size tree = match tree with | Tip _ -> 1 | Node(_,treeLeft,treeRight) -> size treeLeft + size treeRight
  • 78. CPS CaseStudy: Using an extra accumulatorWe just add an extra parameterand weassume (!) thetreeisskewed to the right (1 of 2 options)The call recursing over the right branch is a tail call, the left one isn‘tThus, we still risk a stack overflow for trees that are more skewed to the leftPage 77let recsizeAcc acc tree = match tree with | Tip _ -> 1 + acc | Node(_,treeLeft,treeRight) -> let acc = sizeAcc acc treeLeftsizeAcc acc treeRightlet size tree = sizeAcc 0 tree
  • 79. CPS CaseStudy: UsingContinuationsByusingcontinuations all branches will betail-callsThestackoverflowproblem has beeneliminatedPage 78let 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 asReading Web PagesProcessing a GUI eventhandlerWaitingfor I/O completionIn addition, weshouldleveragethe power of Multicore CPUs Weneedlanguagesupportforreactive, asynchronous, and parallel processingPage 79SocketforAthlon 64 X2 CPUSource: Wikipedia
  • 81. Using Mechanisms from the BCLIn the .NET BCL (Base Class Library) there are already some mechanisms available such as threads and background workersWe 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 81let worker = new BackgroundWorker()let numIterations = 1000worker.DoWork.Add(fun args -> let rec computeFibonacciresPrevPrevresPrev i = let res = resPrevPrev + resPrev if i = numIterations thenargs.Result <- box res // mutable access elsecomputeFibonacciresPrev res (i+1)computeFibonacci 1 1 2)worker.RunWorkerCompleted.Add(fun args ->MessageBox.Show(sprintf "Result = %A" args.Result) |> ignore)worker.RunWorkerAsync()
  • 83. Async ExampleMicrosoft.FSharp.Control.Async<'T> allows to define asynchronous workflowsAn Async instance will provide a result in the future (calling Start)let!, do!, return!, yield! imply asynchronous processingPage 82let 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 HoodInternally, F# uses continuations. For example:will be implemented asPage 83async { 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 ExecutionPage 84open System.Threadingopen Systemlet parallelArrayInit n f =let currentLine = ref -1 // reference let res = Array.zeroCreate n let rec loop () = let y = // locking with InterlockedInterlocked.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.RunSynchronouslyreslet 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 ProgrammingThe class MailboxProcessor allows to implement agents which retrieve messages through their inboxPage 85let 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 agentCounter.Post(42) // send message “42” to agent
  • 87. SummaryF# pragmatically combines imperative (C# roots) with functional programming (OCaml roots)It runs on the CLR and thus offers interoperability with other CLI languagesExcellent features for concurrency and asynchronous operationF# programs are compact and succinct causing less noise-to-signal ratioSupport for Windows, Mac OS, LinuxAvailability on Visual Studio 2010 implies Microsoft is serious about functional languagesStart Coding with F#!Page 86
  • 88. Books: My RecommendationsD. 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 availablePage 87
  • 89. F# Tools Lot of more availableF# PowerPack: tools such as FsLex, FsYacc, (P)LINQ support, additional classes, SI Units for Measure, ...Amazing examples on http://code.msdn.microsoft.com/fsharpsamplesxUnit.net for Unit Testing: http://xunit.codeplex.com/ or NunitF# Web Tools: http://fswebtools.codeplex.com/Page 88
  • 90. F# LinksInteresting Links to F# information/sourcesMicrosoft Research: http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/Microsoft MSDN: http://msdn.microsoft.com/en-us/fsharp/defaultDon 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.aspxYouTube: http://www.youtube.com/watch?v=uyW4WZgwxJEPage 89
  • 91. SummaryF# pragmatically combines imperative (C# roots) with functional programming (OCaml roots)It runs on the CLR and thus offers interoperability with other CLI languagesExcellent features for concurrency and asynchronous operationF# programs are compact and succinct causing less noise-to-signal ratioSupport for Windows, Mac OS, LinuxAvailability on Visual Studio 2010 implies Microsoft is serious about functional languagesStart Coding with F#!Page 90
  • 92. Final ConclusionsFunctional Programmingisnotrestricted to academic researchanymoreBig playersalreadyusetheparadigm such as Facebook, Twitter, EricssonFP languageslikeClojure, Erlang, Scala, F# arenowreadyforthemainstreamIn addition, functionalfeatureshavebeenintegratedinto Java, C++, C#, Ruby, Smalltalk, ..CLR/JVM offerseveralbenefits:InteroperabilityAvailability of richframeworklibrariesAvailability of powerfultoolsAvailability of large communitiesNo Big Bang approachrecommended. Start small, growbigDistributetheword and letthe force bewithyouPage 91