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

OOP is dead only if FP is dead

André Staltz
September 28, 2017

OOP is dead only if FP is dead

It is common to see Functional Programming (FP) presented as the opposite of Object-oriented Programming (OOP). These two programming paradigms have important differences, but they can share a lot in common, so they are not in direct opposition. In this talk, Andre will explore the gray area between OOP and FP, with code samples in JavaScript, TypeScript, and Haskell, kept easy enough enough for any programmer to follow.

André Staltz

September 28, 2017
Tweet

More Decks by André Staltz

Other Decks in Programming

Transcript

  1. OOP is dead 

    only if FP is dead
    @andrestaltz

    View Slide

  2. Is object-oriented programming
    fundamentally different or superficially
    different to functional programming?

    View Slide

  3. OOP FP

    View Slide

  4. Closures
    Objects
    Immutability
    Mutation
    Assignment

    syntax
    Assignment

    semantics
    Typed
    Dynamic Evaluate
    Execute

    View Slide

  5. Evaluate
    Execute

    View Slide

  6. Evaluate
    Execute
    Calculate the value
    of an expression
    Perform a sequence
    of get/set actions

    View Slide

  7. Evaluate
    Execute
    Calculate the value
    of an expression
    Perform a sequence
    of get/set actions
    Imperative
    Functional

    View Slide

  8. Evaluate
    Execute
    (weight =>
    height =>
    weight / 

    (height * height * 0.01 * 0.01)
    )(70)(177)
    var weight = 70;
    var height = 177;
    var bmi = weight;
    bmi /= height;
    bmi /= height;
    bmi /= 0.01;
    bmi /= 0.01;

    View Slide

  9. Evaluate
    Execute
    Foundation is
    Lambda calculus
    Foundation is

    Random access machine

    View Slide

  10. Closures
    Objects

    View Slide

  11. Closures
    Objects
    Put data in an object,
    attach methods to the object
    Put data in a closure,
    functions refer to the closure

    View Slide

  12. Closures
    Objects
    const greeter = {
    isFemale: false,
    greet(name) {
    return this.isFemale ?
    "Hi Ms. " + name :
    "Hi Mr. " + name;
    }
    };
    const greet = (isFemale =>
    name => isFemale ?
    "Hi Ms. " + name :
    "Hi Mr. " + name
    )(false);

    View Slide

  13. Closures
    Objects
    const greeter = {
    // ...
    };
    greeter.greet.bind({isFemale: true})('Lisa');
    Advantage: allows changing the this object for a method.

    View Slide

  14. Closures
    Objects
    const greeter = {
    // ...
    };
    greeter.greet.bind({isFemale: true})('Lisa');
    Advantage: allows changing the this object for a method.
    Disadvantage: allows changing the this object for a method.

    View Slide

  15. Immutability
    Mutation

    View Slide

  16. Immutability
    Mutation

    View Slide

  17. Immutability
    Mutation
    final String s = "ABC";
    s.toLowerCase();
    Java

    View Slide

  18. Immutability
    Mutation
    Haskell
    import Data.Char
    str1 = "ABC"
    str2 = map toLower str1

    View Slide

  19. Immutability
    Mutation
    Haskell
    import Data.IORef
    f :: Num a => a -> IO a
    f x = do
    y <- newIORef 5 -- :: IORef Int
    writeIORef y 10
    val <- readIORef y -- :: Int
    return 2 * val

    View Slide

  20. Immutability
    Mutation
    Haskell
    import Data.STRef
    import Control.Monad.ST
    f :: Num a => a -> a
    f x = runST $ do
    y <- newSTRef 5 -- :: STRef Int
    writeSTRef y 10
    val <- readSTRef y -- :: Int
    return 2 * val

    View Slide

  21. Assignment

    syntax
    Assignment

    semantics

    View Slide

  22. Assignment

    syntax
    Assignment

    semantics
    Haskell
    do
    text <- readFile "foo"
    writeFile "bar" text
    readFile "foo" >>= writeFile "bar"

    View Slide

  23. Assignment

    syntax
    Assignment

    semantics
    Haskell
    do
    text <- readFile "foo"
    writeFile "bar" text
    readFile "foo" >>= writeFile "bar"

    View Slide

  24. Assignment

    syntax
    Assignment

    semantics
    JavaScript
    var text = fs.readFileSync('foo');
    fs.writeFileSync('bar', text);

    View Slide

  25. Assignment

    syntax
    Assignment

    semantics
    strongConnect v graph index stack indices lowlinks output = do
    i <- readSTRef index
    modifySTRef' indices (I.insert v i)
    modifySTRef' lowlinks (I.insert v i)
    modifySTRef' index (+1)
    push stack v
    forM_ (graph A.! v) $ \w -> do
    wIndex <- I.lookup w <$> readSTRef indices
    if isNothing wIndex
    then do
    strongConnect w graph index stack indices lowlinks output
    vLowLink <- fromJust . I.lookup v <$> readSTRef lowlinks
    wLowLink <- fromJust . I.lookup w <$> readSTRef lowlinks
    modifySTRef' lowlinks (I.insert v $ min vLowLink wLowLink)
    else do
    wOnStack <- elem w <$> readSTRef stack
    when wOnStack $ do
    vLowLink <- fromJust . I.lookup v <$> readSTRef lowlinks
    modifySTRef' lowlinks (I.insert v $ min vLowLink (fromJust wIndex))
    vLowLink <- fromJust . I.lookup v <$> readSTRef lowlinks
    vIndex <- fromJust . I.lookup v <$> readSTRef indices
    when (vLowLink == vIndex) $ do
    scc <- addSCC v [] stack
    modifySTRef' output (scc:)
    http://vaibhavsagar.com/blog/2017/05/29/imperative-haskell/

    View Slide

  26. Typed
    Dynamic

    View Slide

  27. Typed
    Dynamic
    Clojure (FP)
    Python (OOP)
    Haskell (FP)
    Java (OOP)

    View Slide

  28. Typed
    Dynamic
    Is x => 2 * x pure?

    View Slide

  29. Typed
    Dynamic
    Is x => 2 * x pure?
    const double = x => 2 * x;
    const lol = {};
    lol.valueOf = Math.random;
    double(lol); // 0.21666564647375441
    double(lol); // 1.4260443726695509

    View Slide

  30. Typed
    Dynamic
    Is x => 2 * x pure?
    const double: (x: number) => number =
    x => 2 * x;

    View Slide

  31. Typed
    Dynamic
    Abstractions: solving problems on the level of ideas

    View Slide

  32. Typed
    Dynamic

    View Slide

  33. Typed
    Dynamic

    View Slide

  34. Typed
    Dynamic
    Abstraction = flexibility.
    integers = [1, 2..]
    list1 = take 5 integers -- [1,2,3,4,5]
    list2 = take 10 integers -- [1,2,3,4,5,6,7,8,9,10]
    Haskell

    View Slide

  35. Typed
    Dynamic
    In Java...
    Objects are concrete. Interfaces are abstract.
    Classes are a bit of both.

    View Slide

  36. Typed
    Dynamic
    In Haskell...
    Basic types
    are concrete.
    Type classes are abstract.
    Abstract Data Types too.

    View Slide

  37. Typed
    Dynamic
    Inheritance
    In OOP: reusability of classes (= data + methods)
    In FP: reusability of type classes (= functions)

    View Slide

  38. Typed
    Dynamic
    Inheritance
    In OOP: reusability of classes (= data + methods)
    In FP: reusability of type classes (= functions)

    View Slide

  39. Typed
    Dynamic
    Inheritance
    In OOP: reusability of classes (= data + methods)
    In FP: reusability of type classes (= functions)

    View Slide

  40. Typed
    Dynamic
    Inheritance
    In OOP: reusability of classes (= data + methods)
    In FP: reusability of type classes (= functions)

    View Slide

  41. Typed
    Dynamic
    Inheritance
    In OOP: reusability of classes (= data + methods)
    In FP: reusability of type classes (= functions)

    View Slide

  42. Typed
    Dynamic
    Inheritance
    In OOP: reusability of classes (= data + methods)
    In FP: reusability of type classes (= functions)

    View Slide

  43. Typed
    Dynamic
    Diamond problem in typed OOP
    Object
    equals()
    Rectangle
    equals()
    Clickable
    equals()
    Button

    View Slide

  44. The real problem is that programmers have spent
    far too much time worrying about efficiency in the
    wrong places and at the wrong times; 

    premature optimization is the root of all evil (or at
    least most of it) in programming. – Donald Knuth

    View Slide

  45. Premature concretization is the root of all
    complexity (or at least most of it) in programming.
    – André Staltz

    View Slide

  46. Typed
    Dynamic
    Haskell can reliably
    do multiple inheritance.

    View Slide

  47. Typed
    Dynamic
    Haskell can reliably
    do multiple inheritance.

    View Slide

  48. Typed
    Dynamic
    JavaScript can unreliably
    do multiple inheritance.

    View Slide

  49. Typed
    Dynamic
    JavaScript can unreliably
    do multiple inheritance.
    // Creating objects
    var o1, o2, o3,
    obj = multiInherit(o1={a:1}, o2={b:2}, o3={a:3, b:3});
    // Setting properties
    obj.c = 3;
    // Reading properties
    obj.a; // 1 (inherited from o1)
    obj.b; // 2 (inherited from o2)
    obj.c; // 3 (own property)
    obj.d; // undefined (not found)
    https://stackoverflow.com/questions/9163341/multiple-inheritance-prototypes-in-javascript/31236132#31236132

    View Slide

  50. Typed
    Dynamic
    JavaScript can unreliably
    do multiple inheritance.
    function multiInherit (...protos) {
    return Object.create(new Proxy(Object.create(null), {
    get (target, prop, receiver) {
    var obj = protos.find(obj => prop in obj);
    return obj ? Reflect.get(obj, prop, receiver) : void 0;
    },
    set (target, prop, value, receiver) {
    var obj = protos.find(obj => prop in obj);
    return Reflect.set(obj || Object.create(null), prop, value, receiver);
    },
    has: (target, prop) => protos.some(obj => prop in obj),
    ownKeys(target) {
    // ...
    },
    getOwnPropertyDescriptor(target, prop) {
    // ...
    },
    *enumerate (target) { yield* this.ownKeys(target); },
    preventExtensions: (target) => false,
    defineProperty: (target, prop, desc) => false,
    }));
    }

    View Slide

  51. Typed
    Dynamic
    Strongly typed FP
    Haskell

    View Slide

  52. Haskell v1.3 Report

    View Slide

  53. Haskell v1.3 Report

    View Slide

  54. Evaluate
    Execute
    Calculate the value
    of an expression
    Perform a sequence
    of get/set actions
    Imperative
    Functional

    View Slide

  55. View Slide

  56. View Slide

  57. OOP FP
    Should we mix everything?

    View Slide

  58. OOP FP
    Should we mix everything?
    Languages should be coherent

    View Slide

  59. Koka
    Typed
    Evaluate
    Immutability
    Assignment syntax
    Closures
    Object syntax

    View Slide

  60. View Slide

  61. View Slide

  62. View Slide

  63. View Slide

  64. View Slide

  65. View Slide

  66. View Slide

  67. View Slide

  68. Closures
    Objects
    Immutability
    Mutation
    Assignment

    syntax
    Assignment

    semantics
    Typed
    Dynamic Evaluate
    Execute
    Thanks : )

    View Slide