Tamizhvendan S
May 29, 2018
320

# Demystifying Functional Programming

Because of some perceived complexities and the mathematical background in functional programming, the beginners get bogged down while learning and putting it into practice. As a matter of fact, few people give up after some initial attempts. But it is not as much harder as we think. It is just different!

Together, let's experience a different perspective of functional programming and get started in a better way

May 29, 2018

## Transcript

1. ### Demystifying Functional Programming tamizhvendan tamizhvendan Lead Consultant www.ajira.tech Tamizhvendan S

Passionate, Pragmatic and Polyglot Programmer https://www.demystifyfp.com λ

8. ### int numbers[3] = {2,3,4}, squaredNumbers[3]; for (int i = 0;

i < 3; i!++) { squaredNumbers[i] = numbers[i] * numbers[i]; }

* n);
10. ### “A language that doesn’t affect the way you think about

programming, is not worth knowing.” - Alan Perlis

21. ### “Data dominates. If you’ve chose the right data structures &

organise things well, the algorithms will almost be self-evident. Data structures, not algorithms, are central to programming” - Rob Pike

23. ### “Make each program do one thing well. To do a

new job, build afresh rather than complicate the old programs by adding new “features”. Expect the output of every program to become the input of another, as yet unknown, program” - Unix Philosophy

25. ### “Design is to take things apart in a such a

way that they can be put back together” - Rich Hickey

29. ### type Attribute = { Name : string Value : string

} <img src="cat.jpg" />
30. ### <img src="cat.jpg" alt="cat" /> type Element = { Name :

string Attributes : Attribute list }
31. ### <p> This is a paragraph </p> type Element = {

Name : string Attributes : Attribute list Content : Content } and Content = PlainText of string
32. ### <textarea rows="4"> </textarea> type Element = { Name : string

Attributes : Attribute list Content : Content option } and Content = PlainText of string
33. ### <ul> <li>Coffee</li> <li>Tea</li> </ul> type Element = { Name :

string Attributes : Attribute list Content : Content option } and Content = | PlainText of string | ChildElements of Element list
34. ### Algebraic Data Types type Element = { Name : string

Attributes : Attribute list Content : Content option } and Content = | PlainText of string | ChildElements of Element list Sum (or Choice) Type Product Type

36. ### Element !-> string let beveragesList = let content = childElements

[ element "li" [] (plainText "Tea") element "li" [] (plainText "Coffee")] element "ul" [("class", "ulist")] content

39. ### // Attribute  string let attrToHtmlStr attr = sprintf @"%s=""%s"""

attr.Name attr.Value

!-> string

44. ### // List<Attribute>  List<string> let attrsToHtmlStr attrs = List.map attrToHtmlStr

attrs (A !-> B) !-> List<A> !-> List<B> List.map
45. ### What we have What we want List<string> !-> string string

!-> List<string> !-> string String.concat

string
47. ### string !-> List<string> !-> string String.concat <img src="cat.jpg" alt="cat" />

String.concat " " string !-> List<string> !-> string
48. ### What we have List<Attribute> !-> List<string> List<string> !-> string What

we want List<Attribute> !-> string
49. ### Expect the output of every program to become the input

of another, as yet unknown, program” - Unix Philosophy

Composition
51. ### Function Composition // List<Attribute>  string let attrsToHtmlStr = List.map

attrToHtmlStr  String.concat " "
52. ### Function Composition Using Piping // List<Attribute>  string let attrsToHtmlStr

attrs = List.map attrToHtmlStr attrs  String.concat " "
53. ### // List<Attribute>  string let attrsToHtmlStr attrs = attrs 

List.map attrToHtmlStr  String.concat " " partial application
54. ### let attrs = [ {Name = "src"; Value = "cat.jpg"}

{Name = "alt"; Value = "cat"} ]
55. ### Map (A !-> B) !-> List<A> !-> List<B> Partial Application

string !-> List<string> !-> string Function Composition A !-> B B !-> C A !-> C

58. ### Pattern Matching // Content  string let contentToHtmlStr content =

match content with | PlainText x  x | ChildElements xs  xs  List.map elementToHtmlStr  String.concat ""

!-> string

61. ### What we have What we want Content !-> string Option<Content>

!-> Option<string>

65. ### let content = defaultArg contentOpt "" Option<string> !-> string core

library function
66. ### What we have What we want Element !-> string Option<Content>

!-> string List<Attribute> !-> string
67. ### let elementToHtmlStr element = let attrs = attrsToHtmlStr element.Attributes let

contentOpt = element.Content  Option.map contentToHtmlStr let content = defaultArg contentOpt “" let tag = element.Name sprintf "<%s %s> %s </%s>" tag attrs content tag
68. ### let beveragesList = let content = childElements [ element "li"

[] (plainText "Tea") element "li" [] (plainText "Coffee")] element "ul" [("class", "ulist")] content

71. ### // int  Result<Element, string> let getElementById id = if

id = 1 then Ok beveragesList else Error "unable to fetch"

!-> string

76. ### // int  Result<int, int> let getHtmlStrById id = getElementById

id  Result.map elementToHtmlStr

79. ### (A !-> B) !-> List<A> !-> List<B> map (A !->

B) !-> Result<A,C> !-> Result<B,C> (A !-> B) !-> F<A> !-> F<B> (A !-> B) !-> Option<A> !-> Option<B>
80. None

83. ### let mergeAttrs attrs1 attrs2 = attrs1 @ attrs2  List.groupBy

(fun (a : Attribute)  a.Name)  List.map (fun (name, attrs)  let value = attrs  List.map (fun a  a.Value)  String.concat " " {Name = name; Value = value} )

85. ### let mergeContent content1 content2 = match content1, content2 with |

PlainText x, PlainText y  sprintf "%s\n%s" x y  PlainText | ChildElements xs, ChildElements ys  ChildElements (xs @ ys) | _  content1
86. ### What we have What we want Element !-> Element !->

Element List<Attribute>  List<Attribute>  List<Attribute> Content  Content  Content
87. ### type Element = { Name : string Attributes : Attribute

list Content : Content option }
88. ### What we have What we want Content  Content 

Content Option<Content> !-> Option<Content> !-> Option<Content>

90. ### let mergeElement e1 e2 = let attrs = mergeAttrs e1.Attributes

e2.Attributes let content = Option.lift2 mergeContent e1.Content e2.Content { Name = e1.Name Attributes = attrs Content = content}

92. ### What we have What we want Element  Element 

Element Result<Element,string> !-> Result<Element,string> !-> Result<Element,string>

94. ### let getAndMergeElements e1Id e2Id = let e1R = getElementById e1Id

let e2R = getElementById e2Id Result.lift2 mergeElement e1R e2R

96. ### A !-> B !-> C Option<A> !-> Option<B> !-> Option<C>

lift2 Result<A,E> !-> Result<B,E> !-> Result<C,E> (A !-> B !-> C) !-> AP<A> !-> AP<B> !-> AP<C> List<A> !-> List<B> !-> List<C>
97. ### map (A !-> B) !-> F<A> !-> F<B> lift2 (A

!-> B !-> C) !-> AP<A> !-> AP<B> !-> AP<C>
98. ### lift3 (A !-> B !-> C !-> D) !-> AP<A>

!-> AP<B> !-> AP<C> !-> AP<D> liftN
99. None
100. ### Each Configuration Has Own Element Id type Configuration = {

Id : int ElementId : int }

103. ### // int  Result<Configuration, string> let getConfigurationById id = if

id = 1 then Ok {Id = 1; ElementId = 1} else Error "unable to fetch"
104. ### What we have What we want int !-> Result<Configuration, string>

int !-> Result<Element, string> int !-> Result<Element, string> configuration id element id configuration id

106. ### let getElementByConfigId cId = getConfigurationById cId  Result.bind (fun c

 getElementById c.ElementId)

108. ### bind (A !-> M<B>) !-> M<A> !-> M<B> (A !->

Result<B, C>) !-> Result<A,C> !-> Result<B, C> (A !-> List<B>) !-> List<A> !-> List<B> (A !-> Option<B>) !-> Option<A> !-> Option<B>
109. ### map (A !-> B) !-> F<A> !-> F<B> lift2 (A

!-> B !-> C) !-> AP<A> !-> AP<B> !-> AP<C> bind (A !-> M<B>) !-> M<A> !-> M<B>

111. ### Prompt<string> let namePrompt : Prompt<string> = stringPrompt "What's Your name?”

> namePrompt();; What’s your name? Tamizhvendan val it : Result<string, PromptError> = Ok “Tamizhvendan”
112. ### Prompt<int> let agePrompt : Prompt<int> = intPrompt "What's Your age?”

> agePrompt();; What’s your age? 29 val it : Result<string, PromptError> = Ok 29 > agePrompt();; What’s your age? foobar val it : Result<string, PromptError> = Error ParserError
113. ### let greeting name age = sprintf "Hey %s, you are

%d years old!” name age let greetingWizard = lift2 greeting namePrompt agePrompt > greetingWizard();; What’s your name? Tamizhvendan What’s your age? 29 val it : Result<string, PromptError> = Ok “Hey Tamizhvendan, you are 29 years old!” lift2
114. ### let addAgeBy10Years age = age + 10 let prankWizard =

agePrompt |> map addAgeBy10Years |> lift2 greeting namePrompt > prankWizard();; What’s your name? Tamizhvendan What’s your age? 29 val it : Result<string, PromptError> = Ok “Hey Tamizhvendan, you are 39 years old!” map
115. ### apply AP<(A !-> B)> !-> AP<A> !-> AP<B> append MO<A>

!-> MO<A> !-> MO<A> fold (A !-> B !-> A) !-> A !-> FO<B> !-> A

!-> AP<T<A>>
117. ### By The Way! M AP F Functor Applicative Monad *

There are some laws!
118. ### FP Demystified λ Algebraic Data Types λ Separate Pure &

Impure Functions λ Function Signature Matters! λ map, liftN, bind, etc., λ Have Fun!! https://www.demystifyfp.com