Download - Functional programming in f sharp
Functional programming in F#
The Why, What and How
Back in the days...
λ LISPISWIM
APLFP
ML
1958 1966
1962
1977
1973
Haskell1988Scala2003Ocaml
1996
F#2005
Clojure2007
1930-ish
Erlang1986
Some definitions
ProgramData - Logic - Control
DeclarativeLogic - Referential transparency
ImperativeLogic - Control - Side effects
Functional programming language
First classHigher-Order Functions
Immutability
Declarative
λ
The PAIN of imperativeness
Screwupability
Shared mutable states
Why not functional programming?
• Too low dev replacability• Legacy code not functional• Bad interop, few libs• Devs find it too hard• Customers don’t care
anyway
Why Functional Programming?
let sum lst = foldr (+) lst 0let product lst = foldr (*) lst 1let append l1 l2 = foldr cons l1 l2let length lst = foldr (+) lst 0let map f lst = foldr (cons << f) lst []
FP demand UK
ScalaClojure
F# Erlang
Real-world uses
F# Svea Ekonomi, Microsoft (Halo), Credit Suisse, Prover
Haskell AT & T, ScriveErlang Ericsson, Klarna, Basho, FacebookLisp Yahoo StoreScala Twitter, LinkedIn
Why F#?
Functional + OO + .NET + Open Source =>The Most Powerful
Language In TheWORLD!
Scala-crowd goes: O rly?Lisp-crowd goes: F-what?
F#
“F# is a practical, functional-first languagethat lets you write simple codeto solve complex problems"
Complex Simplestatic Tree<KeyValuePair<A, bool>> DiffTree<A>(Tree<A> tree, Tree<A> tree2){ return XFoldTree( (A x, Func<Tree<A>, Tree<KeyValuePair<A, bool>>> l,
Func<Tree<A>, Tree<KeyValuePair<A, bool>>> r, Tree<A> t)
=> (Tree<A> t2) => Node(new KeyValuePair<A, bool>(t2.Data,
ReferenceEquals(t, t2)), l(t2.Left), r(t2.Right)), x1 => y => null, tree)(tree2);}
Tree<KeyValuePair<A, bool>> DiffTree<A>(Tree<A> tree, Tree<A> tree2)
{ XFoldTree(
(A x, Func<Tree<A>, Tree<KeyValuePair<A, bool>>> l, Func<Tree<A>, Tree<KeyValuePair<A, bool>>> r, Tree<A> t)
=> (Tree<A> t2) => Node(new KeyValuePair<A, bool>(t2.Data,
ReferenceEquals(t, t2)), l(t2.Left), r(t2.Right)), x1 => y => null, tree)(tree2);}
Complex Simple
DiffTree ( tree, tree2)
{ XFoldTree(
( x, l, r,
t) => (Tree<A> t2) => Node(new KeyValuePair<A, bool>(t2.Data,
ReferenceEquals(t, t2)), l(t2.Left), r(t2.Right)), x1 => y => null, tree)(tree2);}
Complex Simple
DiffTree ( tree, tree2)
{ XFoldTree(
( x, l, r,
t, t2) => Node(new KeyValuePair<A, bool>(t2.Data,
ReferenceEquals(t, t2)), l(t2.Left), r(t2.Right)), x1 => y => null, tree)(tree2);}
Complex Simple
DiffTree ( tree, tree2)
{ XFoldTree(
( x, l, r,
t, t2) =>
let (Node(x2,l2,r2)) = t2 Node((x2,t=t2), l l2, r r2)) (fun _ _ -> Leaf) tree tree2;}
Complex Simple
DiffTree ( tree, tree2)
XFoldTree( x, l,
r, t, t2
=> let (Node(x2,l2,r2)) = t2
Node((x2,t=t2), l l2, r r2)) (fun _ _ -> Leaf) tree tree2
Complex Simple
let DiffTree ( tree, tree2) =
XFoldTree(fun x, l,
r, t, t2
-> let (Node(x2,l2,r2)) = t2
Node((x2,t=t2), l l2, r r2)) (fun _ _ -> Leaf) tree tree2
Complex Simple
let DiffTree( tree, tree2) = XFoldTree(fun x, l, r, t, t2 ->
let (Node(x2,l2,r2)) = t2Node((x2,t=t2), l l2, r r2)) (fun _ _ -> Leaf) tree
tree2
Complex Simple
(Function) values in F#
let ten = 10
let square x = x*x
let squareList = List.map (fun n -> n*n)
let addThree = (+) 3
(Function) values in F#
let outer x = let inner y = printfn "outer + inner = %d" (x + y) inner 21
let rec sum list = match list with | [] -> 0 | head::tail -> head + sum tail
let rec merge l1 l2 = match l1, l2 with | [], xs | xs, [] -> xs | x::xs', (y::_ as ys) when x <= y -> x::merge xs' ys | xs, y::ys' -> y::merge xs ys'
Pattern matching
Named pattern Guarded pattern
Parallel pattern
OR pattern
F# data types
+ *Algebraic Data Types
F# data types - Union
type Shape = | Circle of float | Rectangle of float * float | Triangle of float * float
F# data types – Recursive union
type BinTree = | Leaf of int | Node of BinTree * BinTree
F# data types - Option
type Option<'a> = | Some of 'a | None
F# data types - Option
public Document getDocByID(int id);
VS
val getDocByID : int -> Document option
F# data types - Option
let res = match getDocByID id with | None -> …handle not found…
| Some(d) -> …do something with d…
F# data types - List
type List<'a> = | Nil | Cons of 'a*List<'a>
Nil + 'a*List<'a>
F# data types - List
let l1 = ["a"; "list"; "of"; "strings"]
let l2 = "a"::"consed"::"list"::[]
let l3 = [1..42]
let l4 = [for i in l3 -> i*i]
Higher-order functions
let rec double l =match l with| [] -> List.empty| h::t -> h*2::double t
Higher-order functions
let rec length (l:string list) =match l with
| [] -> List.empty | h::t -> h.Length::length t
Higher-order functions
let rec map f l = match l with
| [] -> List.empty | h::t -> f(h)::map t
Higher-order functions
map (fun x -> 2*x) list
map (fun (x:string) -> x.Length) list
Pipelining
h(g(f(x)))
VS
x |> f |> g |> h
Pipeline operator
Function composition
let f x = h(g(x))
VS
let f = g >> h
Composition operator
Function composition
let double_then_sum = List.map ((*)2) >> List.reduce
(+)
Synchronous -> Asynchronous
let getData (url:string) = let r = WebRequest.Create(url) let resp = r.GetResponse() use stream = resp.GetResponseStream() use reader = new StreamReader(stream) let data = reader.ReadToEnd() data
F# 3.0
• Type Providers• Query Expressions• Triple-quoted strings
Summary
Functional programming lets youFocus on the problem and less on noiseWrite consice and readable codeCreate composable programs
F# gives youAccess to the .NET frameworkCross-platformMultiparadigm for solving real-world problems
So...
λ = Future?
Complex vs Simple
Lots of plumbing vs Logic
Spaghetti vs Composability
Headache vs Fun
?
Jayway
[email protected]@chribbenFunctional Programming Sthlm User GroupJayway seminarsØredev