multiparadigm
functional, imperative and object oriented
Slide 5
Slide 5 text
originally developed by
Microsoft Research
Slide 6
Slide 6 text
now controlled by
F# Foundation
Slide 7
Slide 7 text
Apache 2 Licensed
Runs on: CLR (Mono/.Net)
Compiles to JavaScript
Slide 8
Slide 8 text
originated from ML
inspired by C#, OCAML, Haskell, …
Slide 9
Slide 9 text
Language
Slide 10
Slide 10 text
let x = 5
let y = 10
let z = x + y
z = 10
Basic Syntax (Values)
Slide 11
Slide 11 text
let addStr x y = (x + y).ToString()
val addStr : x:int -> y:int -> string
Basic Syntax (Arrow notation)
Slide 12
Slide 12 text
Type inference
Happens everywhere
Parameters, Values, Generics
Slide 13
Slide 13 text
let add (x : int) (y : int) = x + y
Type inference
Slide 14
Slide 14 text
let add (x : int) (y : int) = x + y
let add x y = x + y
Type inference
Slide 15
Slide 15 text
let add (x : int) (y : int) = x + y
let add x y = x + y
add 5 10
Type inference
Slide 16
Slide 16 text
let add (x : int) (y : int) = x + y
let add x y = x + y
add 5 10
add 3.14 4.56
Type inference
Slide 17
Slide 17 text
let add (x : int) (y : int) = x + y
let add x y = x + y
add 5 10
add 3.14 4.56
add 3.14 10
Type inference
Slide 18
Slide 18 text
let sign num =
if num > 0 then "positive"
elif num < 0 then "negative"
else "zero"
Type inference (more)
Slide 19
Slide 19 text
let sign num =
if num > 0 then "positive"
elif num < 0 then "negative"
else 0
Type inference (more)
Slide 20
Slide 20 text
type IAnimal = interface…
Type inference (more)
Slide 21
Slide 21 text
type IAnimal = interface…
type Dog = class interface IAnimal…
Type inference (more)
Slide 22
Slide 22 text
type IAnimal = interface…
type Dog = class interface IAnimal…
let getName (l : IAnimal) = …
Type inference (more)
Slide 23
Slide 23 text
type IAnimal = interface…
type Dog = class interface IAnimal…
let getName (l : IAnimal) = …
let doStuffWithDog (d : Dog) = …
Type inference (more)
Slide 24
Slide 24 text
type IAnimal = interface…
type Dog = class interface IAnimal…
let getName (l : IAnimal) = …
let doStuffWithDog (d : Dog) = …
let takesStuff s =
doStuffWithDog(s)
getName(s)
Type inference (more)
Slide 25
Slide 25 text
Type inference (Generics)
Slide 26
Slide 26 text
let giveMeAThree x = 3
'a -> int
Type inference (Generics)
Slide 27
Slide 27 text
let throwAwayFirstInput x y = y
'a -> 'b -> 'b
Type inference (Generics)
Slide 28
Slide 28 text
Functional
Programming
Slide 29
Slide 29 text
Pattern Matching
Describes control flow
patterns match sequentially
Checked for completness
Slide 30
Slide 30 text
let getPrice name =
match name with
| "banana" -> 0.79
| "watermelon" -> 3.49
| "tofu" -> 1.09
| _ -> nan
Pattern Matching
Slide 31
Slide 31 text
let getPrice = function
| "banana" -> 0.79
| "watermelon" -> 3.49
| "tofu" -> 1.09
| _ -> nan
Pattern Matching
Slide 32
Slide 32 text
let sign = function
| 0 -> 0
| x when x < 0 -> -1
| x when x > 0 -> 1
Pattern Matching
Slide 33
Slide 33 text
Recursion
Basic concept of FP
Function calling itself
Slide 34
Slide 34 text
let rec fact x =
if x < 1 then 1
else x * fact (x - 1)
Recursion
Slide 35
Slide 35 text
let rec count n =
if n = 1000000 then
printfn "done"
else
if n % 1000 = 0 then
printfn "n: %i" n
count (n + 1)
Recursion (Tail)
Slide 36
Slide 36 text
Higher order functions
Function taking a function as
argument and/or returning a
function
Slide 37
Slide 37 text
let passFive f = (f 5)
val passFive : (int -> 'a) -> 'a
Higher order functions
Slide 38
Slide 38 text
let map it converter = converter it
val map : 'a -> ('a -> 'b) -> 'b
Higher order functions
Slide 39
Slide 39 text
let add x y = x + y
let addFive = add 5
Higher order functions
Slide 40
Slide 40 text
let add x y = x + y
val add : int -> int -> int
let addFive = add 5
val addFive : (int -> int)
Higher order functions
Slide 41
Slide 41 text
Option Types
The “null” of functional
programming
Some or None
Explicitly stat that some can be
nothing
Slide 42
Slide 42 text
> let div x y = x / y
val div : int -> int -> int
> div 10 5
val it : int = 2
> div 10 0
Option Types
Slide 43
Slide 43 text
let sdiv x y =
match y with
| 0 -> None
| _ -> Some(x/y)
val sdiv : int -> int -> int option
Option Types
Slide 44
Slide 44 text
> safediv 10 5
val it : int option = Some 2
> safediv 10 0
val it : int option = None
Option Types
Slide 45
Slide 45 text
let isFortyTwo = function
| Some(42) -> true
| Some(_) | None -> false
> isFortyTwo (Some(43))
val it : bool = false
> isFortyTwo (Some(42))
val it : bool = true
Option Types
Slide 46
Slide 46 text
Tuples
a “Group” of values
Often used for “multiple” return
values
Slide 47
Slide 47 text
> let average (a, b) =
let sum = a + b
sum / 2.0
val average : float * float -> float
> average (10.0, 20.0)
val it : float = 15.0
Tuples
Slide 48
Slide 48 text
> let divrem x y =
match y with
| 0 -> None
| _ -> Some(x / y, x % y)
val divrem : int -> int -> (int * int)
option
Tuples
Slide 49
Slide 49 text
> divrem 100 20
val it : (int * int) option = Some (5, 0)
> divrem 6 4
val it : (int * int) option = Some (1, 2)
Tuples
Slide 50
Slide 50 text
let greeting (name, language) =
match (name, language) with
| ("Steve", _) -> "Howdy, Steve"
| (name, "Engl") -> "Hello, “ + name
| (_, "French") -> "Bonjour!"
| _ -> "DOES NOT COMPUTE"
Tuples
Slide 51
Slide 51 text
Records
Tuples with names values
Slide 52
Slide 52 text
type website =
{ Title : string;
Url : string }
Records
Slide 53
Slide 53 text
type website =
{ Title : string;
Url : string }
> let homepage = { Title = "Google"; Url
= "http://www.google.com" }
val homepage : website
Records
Slide 54
Slide 54 text
> let homepage = { Title = "Wikibooks"; Url =
"http://www.wikibooks.org/" }
val homepage : website
> homepage.Title
val it : string = "Wikibooks"
> homepage.Url
val it : string = "http://www.wikibooks.org/"
Records
Slide 55
Slide 55 text
type TransactionItem =
{ Name : string;
ID : int;
ProcessedText : string;
IsProcessed : bool }
let processItem item =
{ item with
ProcessedText = "Done";
IsProcessed = true }
Records
Slide 56
Slide 56 text
type coords = { X : float; Y : float }
let getQuadrant = function
| { X = 0.0; Y = 0.0 } -> "Origin"
| item when item.X >= 0.0 && item.Y >= 0.0 -> "I"
| item when item.X <= 0.0 && item.Y >= 0.0 ->"II"
| item when item.X <= 0.0 && item.Y <= 0.0 ->"III"
| item when item.X >= 0.0 && item.Y <= 0.0 -> "IV"
Records
Slide 57
Slide 57 text
Lists
ordered collection of values
immutable
linked list
Slide 58
Slide 58 text
> let numbers = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
val numbers : int list
[1; 2; 3; 4; "cat"; 6; 7]
Lists
Slide 59
Slide 59 text
> [1 .. 10]
val it : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
> [1 .. 2 .. 10]
val it : int list = [1; 3; 5; 7; 9]
> ['a' .. 's']
val it : char list
Lists
Slide 60
Slide 60 text
let rec sum total = function
| [] -> total
| hd :: tl -> sum (hd + total) tl
Lists
Slide 61
Slide 61 text
Set / Map
unordered collections
immutable
Slide 62
Slide 62 text
> Set.empty.Add(1).Add(2).Add(7)
val it : Set = set [1; 2; 7]
let a = Set.ofSeq [ 1 .. 10 ]
let b = a
a.Add(12)
b.Add(13)
Set / Map
Slide 63
Slide 63 text
let capitals =
[("Australia", "Canberra"); ("Canada", "Ottawa");
("China", “Beijing”);]
let canadaCapital = capitals.find("Canada")
Set / Map
Slide 64
Slide 64 text
Discriminated Unions
tagged unions
finite set of choices
Slide 65
Slide 65 text
type switchstate =
| On
| Off
let toggle = function
| On -> Off
| Off -> On
let main() =
let x = On
let y = Off
let z = toggle y
Discriminated Unions
Slide 66
Slide 66 text
type switchstate =
| On
| Off
| Adjustable of float
Discriminated Unions
Slide 67
Slide 67 text
Imperative
Programming
(impure!1!!)
Slide 68
Slide 68 text
Mutability
Two types of mutability
re alias
&
references to same memory
Slide 69
Slide 69 text
> let mutable x = 5
val mutable x : int
> x
val it : int = 5
> x <- 10
val it : unit = ()
> x
val it : int = 10
Mutability
Slide 70
Slide 70 text
> let x = ref "hello";;
val x : string ref
> x;; (* returns ref instance *)
val it : string ref = {contents = "hello";}
> !x;; (* returns x.contents *)
val it : string = "hello"
> x := "world";; (* updates x.contents with a new value *)
val it : unit = ()
> !x;; (* returns x.contents *)
val it : string = "world"
Mutability
Slide 71
Slide 71 text
> let cell1 = ref 7;;
val cell1 : int ref
> let cell2 = cell1;;
val cell2 : int ref
> cell1 := 10;;
val it : unit = ()
> !cell1;;
val it : int = 10
> !cell2;;
val it : int = 10
Mutability
Slide 72
Slide 72 text
Typesafe (s)printf
sprintf "Hi, I'm %s and I'm a %s" "Juliet" “Scorpio"
sprintf "I'm %i years old" "kitty"
Slide 73
Slide 73 text
Other
Control flow: if/then, for, while
Arrays: fixed size, mutable, fast
mutable Collections/Maps
Exceptions
Operators: define & overload
Slide 74
Slide 74 text
Object Orientated
Programming
Slide 75
Slide 75 text
OOP
Classes/Interfaces
Events: no magic
modules/namespaces
Slide 76
Slide 76 text
Cool Stuff
Slide 77
Slide 77 text
Unit of Measurement
additional dimension to
typesystem
statically checked
Slide 78
Slide 78 text
Unit of Measurement
[]
type m (* meter *)
[]
type s (* second *)
Slide 79
Slide 79 text
Unit of Measurement
[] type m (* meter *)
[] type s (* second *)
[] type kg (* kilogram *)
[] type N = (kg * m)/(s^2) (* Newtons *)
[] type Pa = N/(m^2) (* Pascals *)
Slide 80
Slide 80 text
Unit of Measurement
> let distance = 100.0
let time = 5.0
let speed = distance / time;;
val distance : float = 100.0
val time : float = 5.0
val speed : float = 20.0
Slide 81
Slide 81 text
Unit of Measurement
type triple<[] 'a> = { a : float<'a>; b :
float<'a>; c : float<‘a>}
{ a = 7.0; b = -10.5<_>; c = 0.5<_> }
val it : triple = {a = 7.0;
b = -10.5;
c = 0.5;}
Slide 82
Slide 82 text
Computation Expressions
the easy monad
Slide 83
Slide 83 text
Computation Expressions
let read_line() = System.Console.ReadLine()
let print_string(s) = printf "%s" s
print_string "What's your name? "
let name = read_line()
print_string ("Hello, " + name)
Slide 84
Slide 84 text
Computation Expressions
let read_line(f) = f(System.Console.ReadLine())
let print_string(s, f) = f(printf "%s" s)
print_string("What's your name? ", fun () ->
read_line(fun name ->
print_string("Hello, " + name, fun () -> () ) )
)
Slide 85
Slide 85 text
Computation Expressions
let getNum msg =
printf "%s" msg
match System.Int32.TryParse(System.Console.ReadLine()) with
| (true, n) when n >= 0 && n <= 100 -> Some(n)
| _ -> None
match getNum "#1: " with
| Some(x) ->
match getNum "#2: " with
| Some(y) ->
match getNum "#3: " with
| Some(z) -> Some(x + y + z)
| None -> None
| None -> None
| None -> None
Slide 86
Slide 86 text
Computation Expressions
let bind(input, rest) =
match System.Int32.TryParse(input()) with
| (true, n) when n >= 0 && n <= 100 -> rest(n)
| _ -> None
let createMsg msg = fun () -> printf "%s" msg;
System.Console.ReadLine()
bind(createMsg "#1: ", fun x ->
bind(createMsg "#2: ", fun y ->
bind(createMsg "#3: ", fun z -> Some(x + y + z) ) ) )
Slide 87
Slide 87 text
Computation Expressions
let bind(input, rest) =
rest(input())
let download (url : string) =
bind( (fun () -> new System.Net.WebClient()), fun webclient ->
bind( (fun () -> webclient.DownloadString(url)), fun html ->
bind( (fun () -> Regex.Matches(html, @"http://\S+") ), fun matches ->
printMsg ("Found " + matches.Count.ToString() + " links")
)
)
)
["http://www.google.com/"; "http://microsoft.com/"; "http://www.wordpress.com/";
"http://www.peta.org"] |> Seq.iter download
Slide 88
Slide 88 text
Computation Expressions
let bind(input, rest) =
ThreadPool.QueueUserWorkItem(new WaitCallback(fun _ -> rest(input())))
let download (url : string) =
bind( (fun () -> new System.Net.WebClient()), fun webclient ->
bind( (fun () -> webclient.DownloadString(url)), fun html ->
bind( (fun () -> Regex.Matches(html, @"http://\S+") ), fun matches ->
printMsg ("Found " + matches.Count.ToString() + " links")
)
)
)
["http://www.google.com/"; "http://microsoft.com/"; "http://www.wordpress.com/";
"http://www.peta.org"] |> Seq.iter download
Slide 89
Slide 89 text
Computation Expressions
let bind(input, rest) =
match System.Int32.TryParse(input()) with
| (true, n) when n >= 0 && n <= 100 -> rest(n)
| _ -> None
let createMsg msg = fun () -> printf "%s" msg;
System.Console.ReadLine()
bind(createMsg "#1: ", fun x ->
bind(createMsg "#2: ", fun y ->
bind(createMsg "#3: ", fun z -> Some(x + y + z) ) ) )
Slide 90
Slide 90 text
Computation Expressions
> type MaybeBuilder() =
member this.Bind(x, f) =
printfn "this.Bind: %A" x
match x with
| Some(x) when x >= 0 && x <= 100 -> f(x)
| _ -> None
member this.Delay(f) = f()
member this.Return(x) = Some x
Slide 91
Slide 91 text
Computation Expressions
let maybe = new MaybeBuilder()
let sugared =
maybe {
let x = 12
let! y = Some 11
let! z = Some 30
return x + y + z
}
Slide 92
Slide 92 text
Computation Expressions
let maybe = new MaybeBuilder()
let desugared =
maybe.Delay(fun () ->
let x = 12
maybe.Bind(Some 11, fun y ->
maybe.Bind(Some 30, fun z ->
maybe.Return(x + y + z)
)
)
)
Slide 93
Slide 93 text
Async Workflows
Based on Computation
Expressions
Used to run code in parallel
Slide 94
Slide 94 text
Async Workflows
let extractLinks url =
async {
let webClient = new System.Net.WebClient()
printfn "Downloading %s" url
let html = webClient.DownloadString(url : string)
printfn "Got %i bytes" html.Length
let matches = Regex.Matches(html, @"http://\S+")
printfn "Got %i links" matches.Count
return url, matches.Count
};;
Mailboxes
type msg =
| Incr of int
| Fetch of AsyncReplyChannel
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop n =
async { let! msg = inbox.Receive()
match msg with
| Incr(x) -> return! loop(n + x)
| Fetch(replyChannel) ->
replyChannel.Reply(n)
return! loop(n) }
loop 0)
Slide 97
Slide 97 text
Mailboxes
> counter.Post(Incr 7);;
val it : unit = ()
> counter.Post(Incr 50);;
val it : unit = ()
> counter.PostAndReply(fun replyChannel -> Fetch
replyChannel);;
val it : int = 57
Slide 98
Slide 98 text
TypeProviders
Compile time generated types
Based on arbitrary information
Slide 99
Slide 99 text
TypeProviders
Slide 100
Slide 100 text
TypeProviders
Slide 101
Slide 101 text
Interested?
Go to:
fshrap.org
fsharpforfunandprofit.com
en.wikibooks.org/wiki/F_Sharp_Programming