Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A (not so) gentle introduction to functional programming

A (not so) gentle introduction to functional programming

Giuseppe Capizzi

February 02, 2015
Tweet

More Decks by Giuseppe Capizzi

Other Decks in Programming

Transcript

  1. What is FP? Functional programming is a programming paradigm that

    treats computation as the evaluation of mathematical functions and avoids side effects and mutable data.
  2. What is FP? • A function doesn’t do anything •

    It’s just a mapping between a domain and a codomain • Input and output values already exist
  3. What is FP? … -1 0 1 2 3 …

    … 0 1 2 3 4 … domain codomain f(x) = x + 1
  4. Values vs identities • A value is something that doesn't

    change • An identity is a stable logical entity associated with a series of different values over time • A state is the value of an identity at a point in time
  5. Values vs identities • Objects are identities • So are

    real world objects, or at least that’s how we perceive them • Typical OOP has imperative programming baked into it
  6. “No man ever steps in the same river twice, for

    it's not the same river and he's not the same man.” — Heraclitus
  7. “Identities are mental tools we use to superimpose continuity on

    a world which is constantly, functionally, creating new values of itself.” — Rich Hickey
  8. Why FP? Functions can be • evaluated lazily • cached

    / memoized • massively parallelized
  9. Throw away your loops! ! sum :: [Int] -> Int

    sum [] = 0 sum (x:xs) = x + sum xs Example 1
  10. FP • Functions • Functions • Functions, also • Functions

    • Yes, functions • Oh my, functions again! • Functions • Functions :) OOP • Single Responsibility Principle • Open/Closed principle • Dependency Inversion Principle • Interface Segregation Principle • Factory pattern • Strategy pattern • Decorator pattern • Visitor pattern From OOP to FP
  11. Functions are values! Let’s take SRP and ISP to the

    extreme: ! interface BunchOfStuff { int doSomething(int x); string doSomethingElse(int x); void doAThirdThing(string x); }
  12. Functions are values! Let’s take SRP and ISP to the

    extreme: ! interface IntToIntFunction { int invoke(int x); }
  13. “Verbs in Javaland are responsible for all the work, but

    as they are held in contempt by all, no Verb is ever permitted to wander about freely. If a Verb is to be seen in public at all, it must be escorted at all times by a Noun.” ! — Steve Yegge
  14. Functions are values! That interface is equivalent to the following

    type: ! Int -> Int which is the type of every function taking an integer and returning an integer.
  15. interface Action { Response call(Request request); } ! interface EmailValidator

    { boolean validateEmail(String email); } Example 2
  16. class UpdateProfile implements Action { private EmailValidator emailValidator; ! public

    UpdateProfile(EmailValidator emailValidator) { this.emailValidator = emailValidator; } ! public Response call(Request request) { … } } Example 2
  17. isValidEmail :: String -> Bool isValidEmail = … ! updateProfile

    :: (String -> Bool) -> Request -> Response updateProfile emailValidation req resp = … ! —— Partial application as Dependency Injection ! updateProfileIfEmailIsValid :: Request -> Response updateProfileIfEmailIsValid = updateProfile isValidEmail ! —— *Any* function of type (String -> Bool) will do! ! updateProfileIfEmailIsPalindrome = updateProfile isPalindrome Example 2
  18. f :: Int -> Int -> Int -> Int f

    x y z = … —— or f x y = \z -> … —— or f x = \y -> \z -> … —— or f = \x -> \y -> \z -> … Currying
  19. sum :: [Int] -> Int sum [] = 0 sum

    (x:xs) = x + sum xs ! prod :: [Int] -> Int prod [] = 1 prod (x:xs) = x * prod xs High-order functions
  20. foldl :: (b -> a -> b) -> b ->

    [a] -> b foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs ! sum :: [Int] -> Int sum = foldl (+) 0 ! prod :: [Int] -> Int prod = foldl (*) 1 High-order functions
  21. map :: (a -> b) -> [a] -> [b] map

    f [] = [] map f (x:xs) = f x : map f xs ! strToUpper :: String -> String strToUpper = map toUpper ! doubleAll :: [Int] -> [Int] doubleAll = map (*2) High-order functions
  22. filter :: (a -> Bool) -> [a] -> [a] filter

    f [] = [] filter f (x:xs) | f x = x : filter f xs | otherwise = filter f xs ! ! filterEven = filter (\x -> x `mod` 2 == 0) filterAlpha = filter isAlpha High-order functions
  23. splitDelim :: String -> String -> [String] splitDelim delim =

    splitRegex (mkRegex delim) ! stringsToInts :: [String] -> [Int] stringsToInts = map read ! sumString :: String -> Int sumString = sum . stringsToInts . splitDelim “,” ! > sumString “1,2,3,4,5” —— 15 Example 3
  24. extractUserAgent :: String -> String extractUserAgent = … ! countUserAgents

    :: String -> Int countUserAgents = length . nub . map extractUserAgent . filter (not . null) . lines Example 4