$30 off During Our Annual Pro Sale. View details »

Introduction to Functional Programming for absolute beginners

Anupam
December 21, 2017

Introduction to Functional Programming for absolute beginners

A 2 hour presentation given at S&P Gurgaon on 21st Dec 2017

Anupam

December 21, 2017
Tweet

More Decks by Anupam

Other Decks in Programming

Transcript

  1. FUNCTIONAL PROGRAMMING FOR ABSOLUTE BEGINNERS ANUPAM JAIN

  2. FUNCTIONAL PROGRAMMING WHO AM I ▸ Programming professionally for over

    12 years ▸ Organise FPNCR Meetup group ▸ The usual suspects - Javascript, Java, Ruby, Python, C ▸ Discovered Functional Programming around 2004 ▸ Lisp -> (OCaml, Erlang) -> Clean -> … -> Haskell ▸ Elm, Purescript, countless others 2 * Please join
  3. FUNCTIONAL PROGRAMMING FP IN NCR ▸ The Delhi/NCR Haskell and

    other Functional Programming Languages Meetup Group ▸ https://www.meetup.com/DelhiNCR-Haskell-And-Functional-Programming- Languages-Group ▸ FPNCR Github Organisation - common projects, propose talks, etc. ▸ https://github.com/fpncr ▸ FPNCR Mailing List ▸ https://groups.google.com/forum/#!forum/fpncr ▸ FPNCR Channel on Slack ▸ https://functionalprogramming.slack.com - #FPNCR 3
  4. FUNCTIONAL PROGRAMMING WHAT IS FUNCTIONAL PROGRAMMING ▸ Functions ▸ Modularity

    ▸ Composition ▸ Abstraction 4 SOFTWARE DESIGN
  5. FUNCTIONAL PROGRAMMING SIMPLICITY ▸ Single Unit of abstraction - Functions

    ▸ Functions are Values ▸ All Values can be passed to Functions 5
  6. FUNCTIONAL PROGRAMMING SIMPLE FUNCTIONS 1 fib :: Integer -> Integer

    2 fib 0 = 1 3 fib 1 = 1 4 fib n = fib (n-1) + fib (n-2) 6
  7. FUNCTIONAL PROGRAMMING CASE EXPRESSIONS 1 fib :: Integer -> Integer

    2 fib n = case n of 3 0 -> 1 4 1 -> 1 5 n -> fib (n-1) + fib (n-2) 7
  8. FUNCTIONAL PROGRAMMING ANONYMOUS FUNCTIONS 1 fib :: Integer -> Integer

    2 fib = \n -> case n of 3 0 -> 1 4 1 -> 1 5 n -> fib (n-1) + fib (n-2) 8
  9. FUNCTIONAL PROGRAMMING GUARDS 1 fib :: Integer -> Integer 2

    fib n 3 | n < 2 = 1 4 | otherwise = fib (n-1) + fib (n-2) 9
  10. FUNCTIONAL PROGRAMMING THINGS THAT MAKE HASKELL UNIQUE ▸ Strongly Typed

    unlike Clojure ▸ Pure unlike OCaml, Scala ▸ Lazy unlike Purescript, Elm 10
  11. FUNCTIONAL PROGRAMMING STRONG STATIC TYPING ▸ Checked at compile time

    ▸ Not the same as Types in, say, Java ▸ Slight Hyperbole - “If it compiles it works” ▸ Reality - “Refactor without fear” ▸ Let the computer help you help yourself 11
  12. FUNCTIONAL PROGRAMMING STRONG STATIC TYPING ▸ Primitive Types ▸ Algebraic

    Data Types ▸ Recursive Types ▸ Function Types ▸ Pattern Matching ▸ Totality 12
  13. FUNCTIONAL PROGRAMMING PRIMITIVE TYPES ▸ Void ▸ () = ()

    ▸ Bool = True | False ▸ Char = ‘a’ | ‘b’ | … ▸ Integer = 0 | 1 | … ▸ String = [Char] 13
  14. FUNCTIONAL PROGRAMMING ALGEBRAIC DATA TYPES 1 data Shape 2 =

    Square 3 | Circle 4 | Triangle 5 6 data User 7 = Root 8 | Login String 14
  15. FUNCTIONAL PROGRAMMING DATA TYPES WITH PARAMS 1 data Maybe a

    2 = Nothing 3 | Just a 4 5 data Either a b 6 = Left a 7 | Right b 15
  16. FUNCTIONAL PROGRAMMING RECURSIVE DATA TYPES 1 data List a 2

    = Empty 3 | Cons a (List a) 4 5 data Tree a 6 = Leaf a 7 | Branch (Tree a) (Tree a) 8 16
  17. FUNCTIONAL PROGRAMMING TYPED FIRST CLASS FUNCTIONS 1 data Ordering 2

    = LT | GT | EQ 3 5 type Cmp a = a -> a -> Ordering 6 7 sort :: Cmp a -> [a] -> [a] 17
  18. FUNCTIONAL PROGRAMMING COMPOSITION VS INHERITANCE ▸ Don’t inherit, compose ▸

    Vehicle > Car > RacingCar ▸ data RacingCar = RacingCar VehicleData CarData RacingCarData 18
  19. FUNCTIONAL PROGRAMMING DEFINING FUNCTIONS WITH PATTERN MATCHING 1 data List

    a 2 = Empty 3 | Cons a (List a) 4 5 cdr :: List a -> List a 6 cdr Empty = ?? 7 cdr (Cons _ rest) = rest 8 9 car :: List a -> a 10 car Empty = ?? 11 car (Cons a _) = a 12 19
  20. FUNCTIONAL PROGRAMMING PATTERN MATCHING (CONTD…) 1 data List a 2

    = Empty 3 | Cons a (List a) 4 5 cdr :: List a -> List a 6 cdr Empty = Empty 7 cdr (Cons _ rest) = rest 8 9 car :: List a -> Maybe a 10 car Empty = Nothing 11 car (Cons a _) = Just a 12 13 data Maybe a = Nothing | Just a 14 20
  21. FUNCTIONAL PROGRAMMING LIST CONCATENATION 1 data List a 2 =

    Empty 3 | Cons a (List a) 4 5 concat :: List a -> List a -> List a 6 concat Empty b = b 7 concat a Empty = a 8 concat (Cons x xs) b@(Cons _ _) 9 = Cons x (concat xs b) 10 21
  22. FUNCTIONAL PROGRAMMING PYTHON 1 class Cell: 2 def __init__( self,

    data, next = None ): 3 self.data = data 4 self.next = next 5 6 def concat(A, B): 7 current = A 8 while current.next != None: 9 current = current.next 10 current.next = B 11 return A 22
  23. HASKELL 101 PYTHON def concat(A, B): current = A while

    current.next != None: current = current.next current.next = B return A 23 concat Empty b = b concat a Empty = a concat (Cons x xs) b = Cons x (concat xs b) HASKELL FIGHT!
  24. HASKELL 101 PYTHON def concat(A, B): current = A while

    current.next != None: current = current.next current.next = B return A 24 concat Empty b = b concat a Empty = a concat (Cons x xs) b = Cons x (concat xs b) HASKELL TEST assertEq(concat('','bar'), 'bar') assertEq(concat('foo',''), 'foo') assertEq(concat(‘foo’,'bar'), 'foobar')
  25. HASKELL 101 PYTHON def concat(A, B): current = A while

    current.next != None: current = current.next current.next = B return A 25 concat Empty b = b concat a Empty = a concat (Cons x xs) b = Cons x (concat xs b) HASKELL
  26. THERE ARE TWO WAYS OF CONSTRUCTING A SOFTWARE DESIGN: ONE

    WAY IS TO MAKE IT SO COMPLICATED THAT THERE ARE NO OBVIOUS DEFICIENCIES, AND THE OTHER WAY IS TO MAKE IT SO SIMPLE THAT THERE ARE OBVIOUSLY NO DEFICIENCIES. - C.A.R. Hoare, 1980 ACM Turing Award Lecture HASKELL 101 26
  27. FUNCTIONAL PROGRAMMING BUT WHAT ABOUT... ▸ Monads? ▸ “It’s just

    Monoids in the category of endofunctors. What is the problem?” ▸ Category Theory ▸ Blah Blah 27
  28. FUNCTIONAL PROGRAMMING You can ignore all the abstract math stuff

    and yet be highly productive with
 Functional Programming 28
  29. FUNCTIONAL PROGRAMMING Haskell lets me write code that I am

    not smart enough to write. 29
  30. ABSTRACTION

  31. HASKELL 101 SUM NUMBERS FROM 1 TO 10 1 total

    = 0, count = 1 2 while count <= 10: 3 total = total + count 4 count = count + 1 31 1 total = sum [1..10]
  32. FUNCTIONAL PROGRAMMING ABSTRACTION ▸ The shared vocabulary that allows us

    to write concise, high level, programs 32
  33. HASKELL 101 SHARED VOCABULARY COMPARED 1 total = 0, count

    = 1 2 while count <= 10: 3 total = total + count 4 count = count + 1 33 1 total = sum [1..10]
  34. FUNCTIONAL PROGRAMMING SUM ELEMENTS OF A LIST 1 sum ::

    [Int] -> Int 2 sum [] = 0 3 sum (x:xs) = x + sum xs 4 34
  35. FUNCTIONAL PROGRAMMING MULTIPLY ELEMENTS OF A LIST 1 prod ::

    [Int] -> Int 2 prod [] = 0 3 prod (x:xs) = x * sum xs 4 35
  36. FUNCTIONAL PROGRAMMING ABSTRACTION 1 fold :: (a -> Int ->

    a) -> a -> [Int] -> a 2 fold _ a [] = a 3 fold f a (x:xs) = fold f (f a x) xs 4 36
  37. FUNCTIONAL PROGRAMMING FOLD OVER ELEMENTS OF A LIST 1 sum

    = fold (+) 0 2 prod = fold (*) 1 3 37
  38. FUNCTIONAL PROGRAMMING IS ANY/ALL BOOLEAN TRUE 1 any = fold

    (||) False 2 all = fold (&&) True 3 38
  39. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS > 3 1 anyLarge =

    fold (\p e -> p || e > 3) False 2 allLarge = fold (\p e -> p && e > 3) True 3 39
  40. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS DIGITS 1 anyDigit = fold

    (\p e -> p || isDigit e) False 2 allDigit = fold (\p e -> p && isDigit e) True 3 40
  41. FUNCTIONAL PROGRAMMING MORE ABSTRACTION! 1 foldMap :: (a -> Int

    -> a) -> (Int -> Int) -> a -> [Int] -> a 2 foldMap _ _ a [] = a 3 foldMap f m a (x:xs) = foldMap f m (f a (m x)) xs 4 41
  42. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS > 3 1 anyLarge =

    foldMap (||) (> 3) False 2 allLarge = foldMap (&&) (> 3) True 3 42
  43. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS DIGITS 1 anyDigit = foldMap

    (||) isDigit False 2 allDigit = foldMap (&&) isDigit True 3 43
  44. FUNCTIONAL PROGRAMMING WHY? 44

  45. FUNCTIONAL PROGRAMMING WHY ▸ Easy to understand what's going on

    ▸ Cleanly separated “logic” ((&&), isdigit, etc.) ▸ Common machinery (foldMap) can be easily reused ▸ Easy to test functions in isolation 45
  46. FUNCTIONAL PROGRAMMING BUT… ▸ foldMap has 3 arguments that are

    not easy to remember ▸ It's harder to generalise this pattern. Should we keep on adding arguments to fold/foldMap? 46
  47. FUNCTIONAL PROGRAMMING WE CAN ABSTRACT FURTHER 1 compose2 :: (a

    -> b -> d) -> (x -> b) -> a -> x -> d 2 compose2 f m a x = f a (m x) 3 foldMap f m a (x:xs) = foldMap f m (f a (m x)) xs 4 = foldMap f m (compose2 f m a x) xs foldMap f m a (x:xs) = fold (compose2 f m) a x xs 47
  48. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS > 3 1 anyLarge =

    fold (compose2 (||) (> 3)) False 2 allLarge = fold (compose2 (&&) (> 3)) True 3 48
  49. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS DIGITS 1 anyDigit = fold

    (compose2 (||) isDigit) False 2 allDigit = fold (compose2 (&&) isDigit) True 3 49
  50. FUNCTIONAL PROGRAMMING MUCH BETTER ▸ We removed an extra function

    (foldMap) which was actually not needed ▸ Our existing machinery (fold) turned out to be powerful enough to support our logic ▸ We reduced code complexity by introducing another “orthogonal” and “generic” shared vocabulary (compose2) 50
  51. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS DIGITS 1 anyDigit = fold

    (compose2 (||) isDigit) False 2 allDigit = fold (compose2 (&&) isDigit) True 3 51
  52. PERFECTION IS ATTAINED NOT WHEN THERE IS NOTHING MORE TO

    ADD, BUT WHEN THERE IS NOTHING MORE TO REMOVE. - Antoine de Saint Exupéry HASKELL 101 52
  53. FUNCTIONAL PROGRAMMING GO DEEPER 1 (.) :: (b -> c)

    -> (a -> b) -> a -> c 2 (.) f g a = f (g a) 3 4 flip :: (a -> b -> c) -> b -> a -> c 5 flip f b a = f a b 6 53
  54. FUNCTIONAL PROGRAMMING ARE ANY/ALL ELEMENTS DIGITS 1 anyDigit = fold

    (flip ((||) . isDigit)) False 2 allDigit = fold (flip ((&&) . isDigit)) True 3 54
  55. FUNCTIONAL PROGRAMMING FUNCTIONS ARE DATA PIPELINES (flip ((||) . isDigit))

    a b = ((||) . isDigit) b a = ((||) (isDigit b)) a = a || isDigit b 55
  56. FUNCTIONAL PROGRAMMING THIS IS SPARTA HASKELL 1 module Main where

    2 3 main :: IO () 4 main = do 5 putStrLn "Hello Haskell!" 6 56
  57. FUNCTIONAL PROGRAMMING THIS IS SPARTA HASKELL 1 module Main where

    2 3 main :: IO () 4 main = do 5 putStrLn "What is your name?" 6 name <- getLine 7 putStrLn ("Hello " ++ name ++ “!") 8 57
  58. FUNCTIONAL PROGRAMMING THIS IS SPARTA HASKELL 1 module Main where

    2 3 main :: IO () 4 main = do 5 name <- getName 6 putStrLn ("Hello " ++ name ++ "!") 7 8 getName :: IO String 9 getName = do 10 putStrLn "What is your name?" 11 getLine 58
  59. FUNCTIONAL PROGRAMMING “IO” DENOTES MUTATION 1 main :: IO ()

    2 main = do 3 name <- getName 4 showGreeting name 5 6 showGreeting :: String -> IO () 7 showGreeting name = putStrLn (greeting name) 8 9 getName :: IO String 10 getName = ... 11 12 greeting :: String -> String 13 greeting name = "Hello " ++ name ++ "!" 59
  60. REAL WORLD

  61. SERVER

  62. FUNCTIONAL PROGRAMMING WAI-ROUTES - TYPE SAFE WEB ROUTING data MyRoute

    = HomeR | HelloR Text renderRoute :: MyRoute -> [Text] parseRoute :: [Text] -> MyRoute 62 Check out https://github.com/ajnsit/wai-routes
  63. FUNCTIONAL PROGRAMMING GENERATED WEB SERVER ROUTING case getPathInfo req of

    "hello" : arg : [] -> case getReqMethod req of GET -> getHello arg req POST -> postHello arg req 63
  64. FUNCTIONAL PROGRAMMING REAL WORLD HASKELL getAlbumsR :: Handler AlbumRoute getAlbumsR

    = runHandlerM $ do Just token <- reqHeader “Authorisation” auth <- liftIO $ post (showRoute ValidateR) token if isValid auth then status 403 >> json err else json albums 64
  65. FUNCTIONAL PROGRAMMING CONCUR - EXTREMELY SIMPLE UI FRAMEWORK main =

    liftIO (R.randomRIO (1,100)) >>= go where go n = do guessStr <- el "div" [] [ text "Try to guess: " , inputEnter [] ] case readMaybe guessStr of Nothing -> go n Just guess -> do if | guess < n -> el_ "div" [] (text $"Go High!") <|> go n | guess > n -> el_ "div" [] (text $"Go Low!") <|> go n | otherwise -> el_ "div" [] (text $ "You guessed it!”) <|> (button [] (text "Play again")) 65 Check out https://github.com/ajnsit/concur
  66. EXTRA TIME

  67. FUNCTIONAL PROGRAMMING FUNCTOR CLASS 1 class Functor f where 2

    fmap :: (a -> b) -> f a -> f b 67
  68. FUNCTIONAL PROGRAMMING FOLDABLE CLASS 1 class Foldable f where 2

    foldr :: (b -> a -> b) -> b -> f a -> b 68
  69. FUNCTIONAL PROGRAMMING LIST INSTANCES 2 instance Functor [] where 3

    fmap f [] = [] 4 fmap f (x:xs) = (f x: map f xs) 5 6 instance Foldable [] where 7 foldl f b [] = b 8 foldl f b (x:xs) = foldl f (f b x) xs 69
  70. FUNCTIONAL PROGRAMMING ANY DATA STRUCTURE CAN BE FOLDED ▸ When

    Data is Non-Recursive, its the same as fmap ▸ When a data structure is recursive, each recursive part needs to be handled separately 70
  71. FUNCTIONAL PROGRAMMING TREE 2 instance Functor Tree where 3 fmap

    f (Leaf a) = Leaf (f a) 4 fmap f (Branch x y) = Branch (fmap f x) (fmap f y) 5 6 instance Foldable Tree where 7 foldl f b (Leaf a) = f b a 8 foldl f b (Branch x y) = ?? (foldl f b x) (foldl f b y) 71
  72. FUNCTIONAL PROGRAMMING FOLD TREE 1 foldTree :: (b -> a

    -> b) -> (b -> b -> b) -> b 2 -> Tree a -> b 3 foldTree f g b (Leaf a) = f b a 4 foldTree f g b (Branch x y) 5 = g (foldTree f g b x) (foldTree f g b y) 72
  73. FUNCTIONAL PROGRAMMING ANOTHER COMMON PATTERN 1 foldTree :: (b ->

    a -> b) -> (b -> b -> b) -> b 2 -> Tree a -> b 3 foldTree f g b (Leaf a) = f b a 4 foldTree f g b (Branch x y) 5 = g (foldTree f g b x) (foldTree f g b y) 73
  74. FUNCTIONAL PROGRAMMING MONOID 1 class Monoid m where 2 (<>)

    :: m -> m -> m 74
  75. FUNCTIONAL PROGRAMMING FOLDABLE TREE REVISITED 1 foldTree :: Monoid b

    => (b -> a -> b) -> b 2 -> Tree a -> b 3 foldTree f b (Leaf a) = f b a 4 foldTree f b (Branch x y) 5 = foldTree f b x <> foldTree f b y 75
  76. FIN Questions?

  77. FUNCTIONAL PROGRAMMING ALGEBRAIC DATA TYPES 1 data Maybe a 2

    = Nothing 3 | Just a 4 5 data Either a b 6 = Left a 7 | Right b 8 9 data Person 10 = Empty 11 | Cons a (List a) 12 13 data Tree a 14 = Leaf a 15 | Branch (Tree a) (Tree a) 16 77
  78. SUPERFICIAL OVERVIEW

  79. FUNCTIONAL PROGRAMMING TEMPLATE HASKELL mkRoute "MyRoute" [parseRoutes| / HomeR GET

    /hello/#Text HelloR GET POST |] 79