Functional thinking, a universal tool for the digital world
Nicolas Rolland August 3, 2014 Nicolas Rolland Functional
prototyping August 3, 2014 1 / 34
Table of Contents 1 Types why types ? Warm-up exercices
IEnumerable and IObservable 2 Universals, programming against the
interface and existentials universals it sounds like L in SOLID ..
existentials 3 Prototyping the functional way Parser combinator
Nicolas Rolland Functional prototyping August 3, 2014 2 / 34
Table of Contents 1 Types why types ? Warm-up exercices
IEnumerable and IObservable 2 Universals, programming against the
interface and existentials universals it sounds like L in SOLID ..
existentials 3 Prototyping the functional way Parser combinator
Nicolas Rolland Functional prototyping August 3, 2014 3 / 34
Types What is a type ? Nicolas Rolland Functional prototyping
August 3, 2014 4 / 34
Types What is a type ? Type A type is a set of values. Nicolas
Rolland Functional prototyping August 3, 2014 4 / 34
Types What is a type ? Type A type is a set of values. why do
we need to think of it in typed functional programming ? a value is
a value e.g. 1 Nicolas Rolland Functional prototyping August 3,
2014 4 / 34
Types What is a type ? Type A type is a set of values. why do
we need to think of it in typed functional programming ? a value is
a value e.g. 1 a function is a value too ! let plus = (+) //fun x y
-> x + y let plusone = plus 1 //fun x -> x + 1 let three =
plusone 2 //3 Nicolas Rolland Functional prototyping August 3, 2014
4 / 34
Types What is a type ? Type A type is a set of values. why do
we need to think of it in typed functional programming ? a value is
a value e.g. 1 a function is a value too ! let plus = (+) //fun x y
-> x + y let plusone = plus 1 //fun x -> x + 1 let three =
plusone 2 //3 hence everything is a value, everything has a type !
Nicolas Rolland Functional prototyping August 3, 2014 4 / 34
Using types Nicolas Rolland Functional prototyping August 3,
2014 5 / 34
Using types by restriction we get correctness - The computer
tells us the errors Nicolas Rolland Functional prototyping August
3, 2014 5 / 34
Using types by restriction we get correctness - The computer
tells us the errors restriction tells readers a specication - We
can communicate to other people Nicolas Rolland Functional
prototyping August 3, 2014 5 / 34
Using types by restriction we get correctness - The computer
tells us the errors restriction tells readers a specication - We
can communicate to other people Types should be helping you, not
get in your way. No need to write the types in F#. Less work AND
more security ! You can write the types for the purpose of
communication with others Nicolas Rolland Functional prototyping
August 3, 2014 5 / 34
Warm-up exercices Nicolas Rolland Functional prototyping August
3, 2014 6 / 34
what can I do with a value of this type ? Type1 () T Nicolas
Rolland Functional prototyping August 3, 2014 7 / 34
what can I do with a value of this type ? Type1 () T let a =
(fun () -> 3) : unit -> int Nicolas Rolland Functional
prototyping August 3, 2014 7 / 34
what can I do with a value of this type ? Type1 () T let a =
(fun () -> 3) : unit -> int lazy values ! Nicolas Rolland
Functional prototyping August 3, 2014 7 / 34
what can I do with a value of this type ? Type1 () T let a =
(fun () -> 3) : unit -> int lazy values ! let delayedValue =
fun () -> someComputationForLater()) T = () T Nicolas Rolland
Functional prototyping August 3, 2014 7 / 34
what can I do with a value of this type ? Type1 () T let a =
(fun () -> 3) : unit -> int lazy values ! let delayedValue =
fun () -> someComputationForLater()) T = () T let delay x = fun
() x : T (() T) let force f = f () : (() T) T delay force = Id()T
force delay = IdT Nicolas Rolland Functional prototyping August 3,
2014 7 / 34
what can I do with a value of this type ? Type2 type Type2 <
T >= | Case1 of (T Type2 < T >) | Case0 Nicolas Rolland
Functional prototyping August 3, 2014 8 / 34
what can I do with a value of this type ? Type2 type Type2 <
T >= | Case1 of (T Type2 < T >) | Case0 let a =
Case1(1,Case1(2,Case1(3,Case0))) Nicolas Rolland Functional
prototyping August 3, 2014 8 / 34
what can I do with a value of this type ? Type2 type Type2 <
T >= | Case1 of (T Type2 < T >) | Case0 let a =
Case1(1,Case1(2,Case1(3,Case0))) This is a list ! match l with |
Case1(value, rest) -> ... //do something with value | Case0
-> ... //do something else Nicolas Rolland Functional
prototyping August 3, 2014 8 / 34
what can I do with a value of this type ? Type3 type RComp <
T >= | NotYet of (() RComp < T >) | Finished of T Nicolas
Rolland Functional prototyping August 3, 2014 9 / 34
what can I do with a value of this type ? Type3 type RComp <
T >= | NotYet of (() RComp < T >) | Finished of T let c =
NotYet(fun () -> (*first part*) NotYet (fun () -> (*second
part*) Finished pi)) Nicolas Rolland Functional prototyping August
3, 2014 9 / 34
what can I do with a value of this type ? Type3 type RComp <
T >= | NotYet of (() RComp < T >) | Finished of T let c =
NotYet(fun () -> (*first part*) NotYet (fun () -> (*second
part*) Finished pi)) Resumable computation ! Nicolas Rolland
Functional prototyping August 3, 2014 9 / 34
can you recognize IEnumerable ? What is a value of type
IEnumerable ? Nicolas Rolland Functional prototyping August 3, 2014
10 / 34
can you recognize IEnumerable ? What is a value of type
IEnumerable ? a sequence of items Nicolas Rolland Functional
prototyping August 3, 2014 10 / 34
can you recognize IEnumerable ? What is a value of type
IEnumerable ? a sequence of items Item type Item of T = | Finished
| Value of T Nicolas Rolland Functional prototyping August 3, 2014
10 / 34
can you recognize IEnumerable ? What is a value of type
IEnumerable ? a sequence of items Item type Item of T = | Finished
| Value of T IEnumerable type IEnumerable < T > = () (() Item
of T) Nicolas Rolland Functional prototyping August 3, 2014 10 /
34
Object Oriented way Nicolas Rolland Functional prototyping
August 3, 2014 11 / 34
Object Oriented way public interface IEnumerator { bool
MoveNext(); Object Current { get; } void Reset(); } public
interface IEnumerable { IEnumerator GetEnumerator(); } How can I
read the protocol ? Should I call MoveNext rst ? What is the value
of current after enumeration is nished ? How can I make sure
current is not used after enumeration is nished ? Nicolas Rolland
Functional prototyping August 3, 2014 11 / 34
IObservable / Reactive type IObservable < T > = (Item of
T ()) () Nicolas Rolland Functional prototyping August 3, 2014 12 /
34
IObservable / Reactive type IObservable < T > = (Item of
T ()) () IEnumerable type IEnumerable < T > = () (() Item of
T) Dont they look similar .... ? Nicolas Rolland Functional
prototyping August 3, 2014 12 / 34
IObservable / Reactive type IObservable < T > = (Item of
T ()) () IEnumerable type IEnumerable < T > = () (() Item of
T) Dont they look similar .... ? why ? Nicolas Rolland Functional
prototyping August 3, 2014 12 / 34
What is a type - take 2 What is a type and why do we need to
think of it ? Nicolas Rolland Functional prototyping August 3, 2014
13 / 34
What is a type - take 2 What is a type and why do we need to
think of it ? Type A type is a computable specication Nicolas
Rolland Functional prototyping August 3, 2014 13 / 34
What is a type - take 2 What is a type and why do we need to
think of it ? Type A type is a computable specication Domain Driven
Design : the architecture is the code Nicolas Rolland Functional
prototyping August 3, 2014 13 / 34
Together Nicolas Rolland Functional prototyping August 3, 2014
14 / 34
Table of Contents 1 Types why types ? Warm-up exercices
IEnumerable and IObservable 2 Universals, programming against the
interface and existentials universals it sounds like L in SOLID ..
existentials 3 Prototyping the functional way Parser combinator
Nicolas Rolland Functional prototyping August 3, 2014 15 / 34
Universals Type let empty () =
System.Collections.Generic.List() let stringList = empty() do
stringList.Add("hello") let intList = empty() do intList.Add(1)
type List = | Empty | Cons of (T * List) let stringList = Empty let
stringList = Cons ("hello", stringList) let intList = Empty let
intList = Cons (1, intList) What is the type of Empty Nicolas
Rolland Functional prototyping August 3, 2014 16 / 34
Universals Type let empty () =
System.Collections.Generic.List() let stringList = empty() do
stringList.Add("hello") let intList = empty() do intList.Add(1)
type List = | Empty | Cons of (T * List) let stringList = Empty let
stringList = Cons ("hello", stringList) let intList = Empty let
intList = Cons (1, intList) What is the type of Empty ? Empty : T.
List < T > What is the type of Cons Nicolas Rolland
Functional prototyping August 3, 2014 16 / 34
Universals Type let empty () =
System.Collections.Generic.List() let stringList = empty() do
stringList.Add("hello") let intList = empty() do intList.Add(1)
type List = | Empty | Cons of (T * List) let stringList = Empty let
stringList = Cons ("hello", stringList) let intList = Empty let
intList = Cons (1, intList) What is the type of Empty ? Empty : T.
List < T > What is the type of Cons ? Cons : T. T List < T
> List < T > Nicolas Rolland Functional prototyping August
3, 2014 16 / 34
Universals What is the type of Empty ? Empty : T. List < T
> I dont need to know anything about the type to do my job, I
will only refer to it opaquely as T implementer of List < T >
does not know T user of List < T > provide the type T Nicolas
Rolland Functional prototyping August 3, 2014 17 / 34
Liskov substitution principle - Program to interface type
ICurrencyQuoteProvider = abstract getQuote : string -> double
type BloombergCurrencyQuoteProvider(licenceToken:obj) = interface
ICurrencyQuoteProvider with member this.getQuote cur = 120.0
//implementation logic type TestQuoteProvider() = interface
ICurrencyQuoteProvider with member this.getQuote cur = 120.0
//program to **interface** type
Basket(curProv:ICurrencyQuoteProvider) = //add to basket etc...
member this.getTotalJPY () = 0.0 //implementation logic member
this.getTotalIn cur = this.getTotalJPY () * curProv.getQuote cur
let testBasket = Basket(TestQuoteProvider()) let prodBasket =
Basket(BloombergCurrencyQuoteProvider(...)) Nicolas Rolland
Functional prototyping August 3, 2014 18 / 34
Existentials Interfaces allows to abstract in object oriented
programming Like universals types, it hides something, but what is
the relation ? Nicolas Rolland Functional prototyping August 3,
2014 19 / 34
Existentials Interfaces allows to abstract in object oriented
programming Like universals types, it hides something, but what is
the relation ? Functional is Mathematics ! Abstraction in FP has to
have a precise denition related to universals ! Nicolas Rolland
Functional prototyping August 3, 2014 19 / 34
Existentials Interfaces allows to abstract in object oriented
programming Like universals types, it hides something, but what is
the relation ? Functional is Mathematics ! Abstraction in FP has to
have a precise denition related to universals ! Universals denition
empty : T. () List < T > suggests existentials absStack :
T{empty : () T push : int T T pop : T T top : T int} Ill use
whatever type I want here; you wont know anything about the type,
so you can only refer to it opaquely as X Nicolas Rolland
Functional prototyping August 3, 2014 19 / 34
absStack : T{empty : () T push : int T T pop : T T top : T int}
implementer Know about the specic type T user does not know about
the specic type T, only about the interface Nicolas Rolland
Functional prototyping August 3, 2014 20 / 34
duality Nicolas Rolland Functional prototyping August 3, 2014
21 / 34
duality IEnumerable vs IObservable Universals vs Existentials
are examples of applying duality Nicolas Rolland Functional
prototyping August 3, 2014 21 / 34
Erik Meijer - he will reverse all your arrows Nicolas Rolland
Functional prototyping August 3, 2014 22 / 34
Functional programming and duality is old : we know it works
Nicolas Rolland Functional prototyping August 3, 2014 23 / 34
encoding in Fsharp // t . Stack(t) type StackOps = { empty :Rep
isEmpty :Rep -> bool push : (int *Rep) -> Rep pop :Rep ->
Rep top :Rep -> int } // t. Stack(t) [] type ExistentialStack()=
// x. ( t . Stack(t) > x) > x = t. Stack(t) abstract Apply :
StackClient -> x and Stack(e:Rep,ops:StackOps)= inherit
ExistentialStack() member this.witness = e member this.getOps = ops
override this.Apply(mc) = mc.Apply(this) and StackClient =
interface // t. Stack(t) > y abstract member Apply : Stack ->
y Nicolas Rolland Functional prototyping August 3, 2014 24 /
34
stack demo Nicolas Rolland Functional prototyping August 3,
2014 25 / 34
Existentials - References Luca Cardelli, Peter Wegner (1985) On
Understanding Types, Data Abstraction, and Polymorphism William
Cook (2009) On Understanding Data Abstraction, Revisited Nicolas
Rolland Functional prototyping August 3, 2014 26 / 34
Table of Contents 1 Types why types ? Warm-up exercices
IEnumerable and IObservable 2 Universals, programming against the
interface and existentials universals it sounds like L in SOLID ..
existentials 3 Prototyping the functional way Parser combinator
Nicolas Rolland Functional prototyping August 3, 2014 27 / 34
How do we go from here to there ? string [a number is like 1234
but can also be 9.12 ] value let b = List([String "a" String
"number" String "is" String "like" NumberI 1234 List ([ String
"but" String "can" String "also" String "be" NumberF 9.12 ]) ])
Nicolas Rolland Functional prototyping August 3, 2014 28 / 34
How do we go from here to there ? string [a number is like 1234
but can also be 9.12 ] value let b = List([String "a" String
"number" String "is" String "like" NumberI 1234 List ([ String
"but" String "can" String "also" String "be" NumberF 9.12 ]) ])
This is a job for ..... Nicolas Rolland Functional prototyping
August 3, 2014 28 / 34
How do we go from here to there ? string [a number is like 1234
but can also be 9.12 ] value let b = List([String "a" String
"number" String "is" String "like" NumberI 1234 List ([ String
"but" String "can" String "also" String "be" NumberF 9.12 ]) ])
This is a job for ..... grep ? Nicolas Rolland Functional
prototyping August 3, 2014 28 / 34
How do we go from here to there ? string [a number is like 1234
but can also be 9.12 ] value let b = List([String "a" String
"number" String "is" String "like" NumberI 1234 List ([ String
"but" String "can" String "also" String "be" NumberF 9.12 ]) ])
This is a job for ..... grep ? imperative ? Nicolas Rolland
Functional prototyping August 3, 2014 28 / 34
How do we go from here to there ? string [a number is like 1234
but can also be 9.12 ] value let b = List([String "a" String
"number" String "is" String "like" NumberI 1234 List ([ String
"but" String "can" String "also" String "be" NumberF 9.12 ]) ])
This is a job for ..... grep ? imperative ? or... Nicolas Rolland
Functional prototyping August 3, 2014 28 / 34
How do we go from here to there ? string [a number is like 1234
but can also be 9.12 ] value let b = List([String "a" String
"number" String "is" String "like" NumberI 1234 List ([ String
"but" String "can" String "also" String "be" NumberF 9.12 ]) ])
This is a job for ..... grep ? imperative ? or... ! Nicolas Rolland
Functional prototyping August 3, 2014 28 / 34
lambda man ! Nicolas Rolland Functional prototyping August 3,
2014 29 / 34
start with the types Nicolas Rolland Functional prototyping
August 3, 2014 30 / 34
start with the types value type type Val = | List of Val list |
NumberI of int | NumberF of double | String of string value let b =
List([String "a" String "number" String "is" String "like" NumberI
1234 List ([ String "but" String "can" String "also" String "be"
NumberF 9.12 ]) ]) Nicolas Rolland Functional prototyping August 3,
2014 30 / 34
parser return type - rst try type ParseReturn = | Success of
ret | Failure of string type Parser = List -> ParseReturn * List
Nicolas Rolland Functional prototyping August 3, 2014 31 / 34
parser return type - rst try type ParseReturn = | Success of
ret | Failure of string type Parser = List -> ParseReturn * List
reading the parser type a parser takes a list of token in it
returns a ParserReturn , and the tokens not yet processed Nicolas
Rolland Functional prototyping August 3, 2014 31 / 34
parser return type - rst try type ParseReturn = | Success of
ret | Failure of string type Parser = List -> ParseReturn * List
reading the parser type a parser takes a list of token in it
returns a ParserReturn , and the tokens not yet processed a
ParserReturn is the value represented by the token consumed Ok,
but........ 9.12 : 9 is a number.. but if we recognize 9 as 9 only,
what do we do for .12 ? = the result of a parser depends also on
the rest of the string If it matters, it should be part of the
returned type of a parser ! Nicolas Rolland Functional prototyping
August 3, 2014 31 / 34
parser return type type ParseReturn = | Success of ret *(token
list) | Failure of string type Parser = token list ->
ParseReturn e.g. 9.12 reading the parser type Each success contains
a recognized value along with the rest Because the notion of what
is the rest is dependent on the Val produced ParseReturn now
contains a coherent and actionable unit of information Nicolas
Rolland Functional prototyping August 3, 2014 32 / 34
demo time Nicolas Rolland Functional prototyping August 3, 2014
33 / 34
There are many more tricks to practice Nicolas Rolland
Functional prototyping August 3, 2014 34 / 34
The End Nicolas Rolland Functional prototyping August 3, 2014
35 / 34