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

A (not so) gentle introduction to functional pr...

A (not so) gentle introduction to functional programming

Avatar for Giuseppe Capizzi

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