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

Ruby Function Composition

Ruby Function Composition

Ruby can elegantly blend both Functional Programming and Object Oriented design patterns together with minimal effort. In this talk, I'll combine both of these design patterns by briefly walking you through the fundamentals of functional composition, appling monads, and finally wrapping all of this up in a nice transactional pipeline object composed of multiple -- and fault tolerant -- operations for building more robust architectures. You'll learn a lot and walk away with new patterns to apply to your own code base.

Brooke Kuhlmann

October 07, 2023
Tweet

More Decks by Brooke Kuhlmann

Other Decks in Programming

Transcript

  1. Ruby Function Composition
    Presented by Brooke Kuhlmann
    g(f(x))
    f(x)
    x
    A B C
    f g

    View full-size slide

  2. Ruby
    Overview
    Fundamentals

    View full-size slide

  3. Dry Monads
    Ruby
    Overview
    Fundamentals
    Railway Pattern

    View full-size slide

  4. Transactable
    Dry Monads
    Ruby
    Overview
    Fundamentals
    Railway Pattern
    Fault tolerent pipelines

    View full-size slide

  5. https://en.wikipedia.org/wiki/Function_composition_(computer_science)
    What

    View full-size slide

  6. https://en.wikipedia.org/wiki/Function_composition_(computer_science)
    What
    "[F]unction composition is an act or mechanism to combine simple
    functions to build more complicated ones. Like the usual
    composition of functions in mathematics, the result of each
    function is passed as the argument of the next, and the result of
    the last one is the result of the whole."
    -- Wikipedia

    View full-size slide

  7. https://www.alchemists.io/articles/ruby_function_composition
    What

    View full-size slide

  8. https://www.alchemists.io/articles/ruby_function_composition
    What

    View full-size slide

  9. https://www.alchemists.io/articles/ruby_function_composition
    What

    View full-size slide

  10. https://www.alchemists.io/articles/ruby_function_composition
    What

    View full-size slide

  11. https://www.alchemists.io/articles/ruby_function_composition
    What
    1

    View full-size slide

  12. https://www.alchemists.io/articles/ruby_function_composition
    What
    1
    2

    View full-size slide

  13. https://www.alchemists.io/articles/ruby_function_composition
    What
    1
    2 3

    View full-size slide

  14. https://www.alchemists.io/articles/ruby_function_composition
    What

    View full-size slide

  15. https://www.alchemists.io/articles/ruby_function_composition
    What
    (5 + 3) * 3 = 24

    View full-size slide

  16. History
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  17. History
    Ruby 2.6.0
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  18. History
    Ruby 2.6.0
    Methods: #>> #<<
    https://www.alchemists.io/articles/ruby_function_composition
    (forward composition) (backward composition)

    View full-size slide

  19. History
    Ruby 2.6.0
    Methods:
    Proc Method
    #>> #<<
    Objects:
    https://www.alchemists.io/articles/ruby_function_composition
    (forward composition) (backward composition)

    View full-size slide

  20. Fundamentals

    View full-size slide

  21. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  22. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    Procs Lambdas Methods Classes

    View full-size slide

  23. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  24. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m
    3|
    | | | | | | | | | |
    Procs

    View full-size slide

  25. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m
    3|
    | | | | | | | | | |
    Procs

    View full-size slide

  26. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m
    3|
    | | | | | | | | | |
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # #
    Procs

    View full-size slide

  27. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m
    3|
    | | | | | | | | | |
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # #
    m
    m m m m m m m m m m m m m m m m m
    # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    Procs

    View full-size slide

  28. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m
    3|
    | | | | | | | | | |
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # #
    m
    m m m m m m m m m m m m m m m m m
    # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    m
    m m m m m m m m m m m m m m
    3 #
    #
    Procs

    View full-size slide

  29. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    multiplier = proc { |number, by = 3| number * by }
    multiplier.class # Proc
    multiplier.inspect # #
    multiplier.call 3 # 9
    multiplier.call 3, 10 # 30
    Procs

    View full-size slide

  30. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  31. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m
    m
    m m m m m m m
    3
    Lam
    bdas

    View full-size slide

  32. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m
    m
    m m m m m m m
    3
    Lam
    bdas

    View full-size slide

  33. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m
    m
    m m m m m m m
    3
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # #
    Lam
    bdas

    View full-size slide

  34. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m
    m
    m m m m m m m
    3
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    Lam
    bdas

    View full-size slide

  35. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m
    m
    m m m m m m m
    3
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    Lam
    bdas

    View full-size slide

  36. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    m
    m m m m m m m m m m m m m m
    m
    m m m m m m m
    3
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    m
    m m m m m m m m m m m m m m
    3 #
    #
    Lam
    bdas

    View full-size slide

  37. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    multiplier = -> number, by = 3 { number * by }
    multiplier.class # Proc
    multiplier.inspect # "#"
    multiplier.call 3 # 9
    multiplier.call 3, 10 # 30
    Lam
    bdas

    View full-size slide

  38. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  39. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    M
    ethods

    View full-size slide

  40. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    M
    ethods

    View full-size slide

  41. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    M
    ethods

    View full-size slide

  42. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    M
    ethods

    View full-size slide

  43. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    M
    ethods

    View full-size slide

  44. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # #
    M
    ethods

    View full-size slide

  45. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    M
    ethods

    View full-size slide

  46. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    M
    ethods

    View full-size slide

  47. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    m
    m m m m m m m m m m m m m m
    3 #
    #
    M
    ethods

    View full-size slide

  48. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    m
    m m m m m m m m m m m m m m
    3 #
    #
    m
    m m m m m m m m m m m m m m
    3, 1
    1
    #
    # #
    M
    ethods

    View full-size slide

  49. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    m
    m m m m m m m m m m m m m m
    3 #
    #
    m
    m m m m m m m m m m m m m m
    3, 1
    1
    #
    # #
    f
    f f f f f f f f f f f f f f f f f f f f f f f f f f
    M
    ethods

    View full-size slide

  50. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    C
    C C C C C C C C C C C C C C C C C C C C
    d
    d d d d d d
    .m
    m m m m m m m
    (
    ( ( ( ( ( ( ( ( ( (
    3)
    ) ) ) ) ) ) ) ) ) ) )
    m
    m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m
    m
    m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    m
    m m m m m m m m m m m m m m
    3 #
    #
    m
    m m m m m m m m m m m m m m
    3, 1
    1
    #
    # #
    f
    f f f f f f f f f f f f f f f f f f f f f f f f f f
    f
    f f f f f f f f
    c
    c c c c
    #
    # # # #
    M
    ethods

    View full-size slide

  51. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    Calculate = Module.new { def self.multiply(number, by = 3) = number * by }
    multiplier = Calculate.method :multiply
    multiplier.class # Method
    multiplier.inspect # "#"
    multiplier.call 3 # 9
    multiplier.call 3, 10 # 30
    function = multiplier.to_proc
    function.class # Proc
    function.inspect # #
    M
    ethods

    View full-size slide

  52. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    Calculate = Module.new { def self.multiply(number, by = 3) = number * by }
    multiplier = Calculate.method :multiply
    multiplier.class # Method
    multiplier.inspect # "#"
    multiplier.call 3 # 9
    multiplier.call 3, 10 # 30
    function = multiplier.to_proc
    function.class # Proc
    function.inspect # #
    M
    ethods

    View full-size slide

  53. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  54. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    c
    c c c c
    d
    d d
    3
    @
    @ @
    e
    e e
    d
    d d
    c
    c c c
    (
    ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
    p
    p p p p p p
    e
    e e
    C
    lasses

    View full-size slide

  55. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    c
    c c c c
    d
    d d
    3
    @
    @ @
    e
    e e
    d
    d d
    c
    c c c
    (
    ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
    p
    p p p p p p
    e
    e e
    C
    lasses

    View full-size slide

  56. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    c
    c c c c
    d
    d d
    3
    @
    @ @
    e
    e e
    d
    d d
    c
    c c c
    (
    ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
    p
    p p p p p p
    e
    e e
    C
    lasses

    View full-size slide

  57. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    c
    c c c c
    d
    d d
    3
    @
    @ @
    e
    e e
    d
    d d
    c
    c c c
    (
    ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
    p
    p p p p p p
    e
    e e
    m
    m m m m m m m m m m m m m m m m m m m m m m m m
    C
    lasses

    View full-size slide

  58. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    c
    c c c c
    d
    d d
    3
    @
    @ @
    e
    e e
    d
    d d
    c
    c c c
    (
    ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
    p
    p p p p p p
    e
    e e
    m
    m m m m m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # # # # # #
    C
    lasses

    View full-size slide

  59. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    c
    c c c c
    d
    d d
    3
    @
    @ @
    e
    e e
    d
    d d
    c
    c c c
    (
    ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
    p
    p p p p p p
    e
    e e
    m
    m m m m m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    C
    lasses

    View full-size slide

  60. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    c
    c c c c
    d
    d d
    3
    @
    @ @
    e
    e e
    d
    d d
    c
    c c c
    (
    ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (
    p
    p p p p p p
    e
    e e
    m
    m m m m m m m m m m m m m m m m m m m m m m m m
    m
    m m m m m m m m m m
    c
    c c c c
    #
    # # # # # # # # # #
    m
    m m m m m m m m m m m m m m m m m
    #
    #
    #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    m
    m m m m m m m m m m m m m m
    3 #
    #
    C
    lasses

    View full-size slide

  61. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    class Multiplier
    def initialize by = 3
    @by = by
    end
    def call(number) = number * by
    private
    attr_reader :by
    end
    multiplier = Multiplier.new
    multiplier.class # Multiplier
    multiplier.inspect # "#"
    multiplier.call 3 # 9
    Multiplier.new(10).call 3 # 30
    C
    lasses

    View full-size slide

  62. Fundamentals
    https://www.alchemists.io/articles/ruby_function_composition
    class Multiplier
    def initialize by = 3
    @by = by
    end
    def call(number) = number * by
    private
    attr_reader :by
    end
    multiplier = Multiplier.new
    multiplier.class # Multiplier
    multiplier.inspect # "#"
    multiplier.call 3 # 9
    Multiplier.new(10).call 3 # 30
    C
    lasses

    View full-size slide

  63. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    Procs Lambdas Methods Classes
    >> >> >>

    View full-size slide

  64. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    Procs Lambdas Methods Classes
    >> >> >>

    View full-size slide

  65. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    Procs
    Lambdas Methods
    Classes
    >> >> >>

    View full-size slide

  66. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    Procs
    Lambdas
    Methods Classes
    >> >> >>

    View full-size slide

  67. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  68. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    © Wallpaper Cave
    Some assembly required.

    View full-size slide

  69. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  70. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    module Composable
    def >>(other) = method(:call) >> other
    def <<(other) = method(:call) << other
    def call = fail NotImplementedError, "`#{self.class.name}##{__method__}` must be implemented."
    end

    View full-size slide

  71. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    module Composable
    def >>(other) = method(:call) >> other
    def <<(other) = method(:call) << other
    def call = fail NotImplementedError, "`#{self.class.name}##{__method__}` must be implemented."
    end

    View full-size slide

  72. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    module Composable
    def >>(other) = method(:call) >> other
    def <<(other) = method(:call) << other
    def call = fail NotImplementedError, "`#{self.class.name}##{__method__}` must be implemented."
    end
    Transactable

    View full-size slide

  73. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    Class

    View full-size slide

  74. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    class Divider
    include Composable
    def initialize by = 3
    @by = by
    end
    def call(number) = number / by
    private
    attr_reader :by
    end
    Class

    View full-size slide

  75. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    class Divider
    include Composable
    def initialize by = 3
    @by = by
    end
    def call(number) = number / by
    private
    attr_reader :by
    end
    Class

    View full-size slide

  76. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    Method

    View full-size slide

  77. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    module Calculate
    def self.multiply(number, by = 3) = number * by
    end
    Method

    View full-size slide

  78. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  79. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    adder = proc { |number, by = 3| number + by }
    subtracter = -> number, by = 3 { number - by }
    divider = Divider.new
    multiplier = Calculate.method :multiply

    View full-size slide

  80. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    adder = proc { |number, by = 3| number + by }
    subtracter = -> number, by = 3 { number - by }
    divider = Divider.new
    multiplier = Calculate.method :multiply
    Proc

    View full-size slide

  81. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    adder = proc { |number, by = 3| number + by }
    subtracter = -> number, by = 3 { number - by }
    divider = Divider.new
    multiplier = Calculate.method :multiply
    Proc
    Lambda

    View full-size slide

  82. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    adder = proc { |number, by = 3| number + by }
    subtracter = -> number, by = 3 { number - by }
    divider = Divider.new
    multiplier = Calculate.method :multiply
    Proc
    Lambda
    Class

    View full-size slide

  83. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    adder = proc { |number, by = 3| number + by }
    subtracter = -> number, by = 3 { number - by }
    divider = Divider.new
    multiplier = Calculate.method :multiply
    Proc
    Lambda
    Class
    Method

    View full-size slide

  84. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    adder = proc { |number, by = 3| number + by }
    subtracter = -> number, by = 3 { number - by }
    divider = Divider.new
    multiplier = Calculate.method :multiply
    Proc
    Lambda
    Class
    Method
    Composable

    View full-size slide

  85. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    multiplier


    (method)
    subtractor


    (lambda)
    adder


    (proc)
    divider


    (class)
    >> >> >>

    View full-size slide

  86. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    multiplier


    (method)
    subtractor


    (lambda)
    adder


    (proc)
    divider


    (class)
    >> >> >>

    View full-size slide

  87. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  88. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39

    View full-size slide

  89. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    Forward composition

    View full-size slide

  90. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    Forward composition
    Backward composition

    View full-size slide

  91. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39

    View full-size slide

  92. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39

    View full-size slide

  93. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    (10 + 3) * 3 = 39

    View full-size slide

  94. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    (10 + 3) * 3 = 39
    📖

    View full-size slide

  95. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    (10 + 3) * 3 = 39
    📖
    1

    View full-size slide

  96. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    (10 + 3) * 3 = 39
    📖
    1

    View full-size slide

  97. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    (10 + 3) * 3 = 39
    📖
    1

    View full-size slide

  98. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    (10 + 3) * 3 = 39
    📖
    1
    2

    View full-size slide

  99. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39
    (10 + 3) * 3 = 39
    📖
    1
    2

    View full-size slide

  100. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39

    View full-size slide

  101. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (multiplier << adder).call 10 # 39

    View full-size slide

  102. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  103. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier >> subtracter >> divider).call 10 # 12
    (divider << subtracter << multiplier << adder).call 10 # 12

    View full-size slide

  104. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier >> subtracter >> divider).call 10 # 12
    (divider << subtracter << multiplier << adder).call 10 # 12
    (((10 + 3) * 3) - 3) / 3 = 12

    View full-size slide

  105. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier >> subtracter >> divider).call 10 # 12
    (divider << subtracter << multiplier << adder).call 10 # 12
    (((10 + 3) * 3) - 3) / 3 = 12

    View full-size slide

  106. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier >> subtracter >> divider).call 10 # 12
    (divider << subtracter << multiplier << adder).call 10 # 12
    (((10 + 3) * 3) - 3) / 3 = 12

    View full-size slide

  107. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  108. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    a
    a a a
    a
    a a a a a a a a a a a a
    a
    a a a a a a a a a a a a a a a a

    View full-size slide

  109. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    a
    a a a
    a
    a a a a a a a a a a a a
    a
    a a a a a a a a a a a a a a a a
    s
    s s s s s s s s s s s s s s s s s s s
    s
    s s s s s s s s s s s s s s s s s s

    View full-size slide

  110. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    a
    a a a
    a
    a a a a a a a a a a a a
    a
    a a a a a a a a a a a a a a a a
    s
    s s s s s s s s s s s s s s s s s s s
    s
    s s s s s s s s s s s s s s s s s s
    a
    a a a a a a a a a a a a a a a a a
    a
    a a a
    a
    a a a a a a a a a a
    a
    a a a
    a
    a a a a a a a a a a a a a a a a a a
    a
    a a a
    a
    a a a a a a a a a

    View full-size slide

  111. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    add_and_multiply = adder >> multiplier
    subtract_and_divide = subtracter >> divider
    add_multiply_subtract_and_divide = add_and_multiply >> subtract_and_divide
    add_multiply_subtract_and_divide.call 10 # 12

    View full-size slide

  112. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    add_and_multiply = adder >> multiplier
    subtract_and_divide = subtracter >> divider
    add_multiply_subtract_and_divide = add_and_multiply >> subtract_and_divide
    add_multiply_subtract_and_divide.call 10 # 12
    (((10 + 3) * 3) - 3) / 3 = 12

    View full-size slide

  113. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  114. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> multiplier).call 10 # 39
    (adder << multiplier).call 10 # 33
    Order of operations matters!

    View full-size slide

  115. Composition
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  116. Composition
    https://www.alchemists.io/articles/ruby_function_composition
    (adder >> Divider.new(0) >> multiplier).call 10 # ZeroDivisionError: divided by 0
    Any error will halt the operation.

    View full-size slide

  117. A Better Way?

    View full-size slide

  118. https://www.alchemists.io/projects/transactable

    View full-size slide

  119. https://www.alchemists.io/projects/transactable
    Transactable

    View full-size slide

  120. https://www.alchemists.io/projects/transactable
    Transactable
    Dry Monads
    Composition

    View full-size slide

  121. https://www.alchemists.io/projects/transactable
    Transactable
    Dry Monads
    Composition

    View full-size slide

  122. https://www.alchemists.io/projects/transactable
    Pipeline
    (Railway Pattern)

    View full-size slide

  123. https://www.alchemists.io/projects/transactable

    Pipeline
    (Railway Pattern)

    View full-size slide

  124. https://www.alchemists.io/projects/transactable

    Pipeline
    (Railway Pattern)

    View full-size slide

  125. https://www.alchemists.io/projects/transactable


    Pipeline
    (Railway Pattern)

    View full-size slide

  126. https://www.alchemists.io/projects/transactable


    Pipeline
    (Railway Pattern)

    View full-size slide

  127. https://www.alchemists.io/projects/transactable



    Pipeline
    (Railway Pattern)

    View full-size slide

  128. https://www.alchemists.io/projects/transactable




    Pipeline
    (Railway Pattern)

    View full-size slide

  129. https://www.alchemists.io/projects/transactable




    Success
    Success
    Success
    Pipeline
    (Railway Pattern)

    View full-size slide

  130. https://www.alchemists.io/projects/transactable




    Success
    Success
    Success
    Failure
    Failure
    Failure
    Pipeline
    (Railway Pattern)

    View full-size slide

  131. https://www.alchemists.io/projects/transactable




    Success
    Success
    Success
    Failure
    Failure
    Failure
    Pipeline
    No Exceptions!
    (Railway Pattern)

    View full-size slide

  132. https://kurzgesagt.org

    View full-size slide

  133. Kurzgesagt
    https://kurzgesagt.org

    View full-size slide

  134. Kurzgesagt
    (in a nutshell)
    https://kurzgesagt.org

    View full-size slide

  135. https://dry-rb.org/gems/dry-monads

    View full-size slide

  136. Dry Monads
    https://dry-rb.org/gems/dry-monads

    View full-size slide

  137. Dry Monads
    https://dry-rb.org/gems/dry-monads

    View full-size slide

  138. Dry Monads
    https://dry-rb.org/gems/dry-monads
    ✅ ❌

    View full-size slide

  139. Dry Monads
    https://dry-rb.org/gems/dry-monads
    Success
    ✅ ❌

    View full-size slide

  140. Dry Monads
    https://dry-rb.org/gems/dry-monads
    Success Failure
    ✅ ❌

    View full-size slide

  141. Dry Monads
    https://dry-rb.org/gems/dry-monads
    Success Failure
    ✅ ❌

    View full-size slide

  142. Dry Monads
    https://dry-rb.org/gems/dry-monads
    Success Failure
    ✅ ❌
    Ok

    View full-size slide

  143. Dry Monads
    https://dry-rb.org/gems/dry-monads
    Success Failure
    ✅ ❌
    Ok Err

    View full-size slide

  144. Dry Monads
    https://dry-rb.org/gems/dry-monads
    Success Failure
    ✅ ❌
    Ok Err
    Union Composite

    View full-size slide

  145. A Quick Script
    📝

    View full-size slide

  146. A Quick Script
    📝
    🔎

    View full-size slide

  147. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  148. Transactable
    require "bundler/inline"
    gemfile true do
    source "https://rubygems.org"
    gem "amazing_print"
    gem "debug"
    gem "http"
    gem "dry-monads"
    gem "transactable"
    end
    Install
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  149. Transactable
    require "bundler/inline"
    gemfile true do
    source "https://rubygems.org"
    gem "amazing_print"
    gem "debug"
    gem "http"
    gem "dry-monads"
    gem "transactable"
    end
    Install
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  150. Transactable
    require "bundler/inline"
    gemfile true do
    source "https://rubygems.org"
    gem "amazing_print"
    gem "debug"
    gem "http"
    gem "dry-monads"
    gem "transactable"
    end
    Install
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  151. Transactable
    require "bundler/inline"
    gemfile true do
    source "https://rubygems.org"
    gem "amazing_print"
    gem "debug"
    gem "http"
    gem "dry-monads"
    gem "transactable"
    end
    Install
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  152. Transactable
    require "bundler/inline"
    gemfile true do
    source "https://rubygems.org"
    gem "amazing_print"
    gem "debug"
    gem "http"
    gem "dry-monads"
    gem "transactable"
    end
    Install
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  153. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  154. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  155. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  156. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  157. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  158. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  159. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  160. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  161. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  162. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition
    Domain Speci
    fi
    c Language (DSL)

    View full-size slide

  163. Transactable
    class Pinger
    include Transactable
    def initialize client: HTTP
    @client = client
    end
    def call url
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    end
    end
    Im
    plem
    entation
    https://www.alchemists.io/articles/ruby_function_composition
    Domain Speci
    fi
    c Language (DSL)

    View full-size slide

  164. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  165. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  166. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition
    🎗 method(:get)

    View full-size slide

  167. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition
    Monad

    View full-size slide

  168. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  169. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition
    Function Map

    View full-size slide

  170. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  171. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  172. Transactable
    class Pinger
    include Transactable
    # ...
    private
    attr_reader :client
    def get result
    result.fmap { |url| client.timeout(1).get url }
    rescue HTTP::TimeoutError => error
    Failure error.message
    end
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  173. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  174. Transactable
    class Pinger
    include Transactable
    # ...
    private
    # ...
    def report(result) = result.fmap { |status| status == 200 ? "Site is up!" : status }
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  175. Transactable
    class Pinger
    include Transactable
    # ...
    private
    # ...
    def report(result) = result.fmap { |status| status == 200 ? "Site is up!" : status }
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition
    🎗 method(:report)

    View full-size slide

  176. Transactable
    class Pinger
    include Transactable
    # ...
    private
    # ...
    def report(result) = result.fmap { |status| status == 200 ? "Site is up!" : status }
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition
    Monad

    View full-size slide

  177. Transactable
    class Pinger
    include Transactable
    # ...
    private
    # ...
    def report(result) = result.fmap { |status| status == 200 ? "Site is up!" : status }
    end
    Privates
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  178. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  179. Transactable
    include Dry::Monads[:result]
    url = "https://xkcd.com"
    case Pinger.new.call(url)
    in Success(message) then puts "Success: #{message}"
    in Failure(error) then puts "Site is down or invalid. Reason: #{error}"
    end
    Execution
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  180. Transactable
    include Dry::Monads[:result]
    url = "https://xkcd.com"
    case Pinger.new.call(url)
    in Success(message) then puts "Success: #{message}"
    in Failure(error) then puts "Site is down or invalid. Reason: #{error}"
    end
    Execution
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  181. Transactable
    include Dry::Monads[:result]
    url = "https://xkcd.com"
    case Pinger.new.call(url)
    in Success(message) then puts "Success: #{message}"
    in Failure(error) then puts "Site is down or invalid. Reason: #{error}"
    end
    Execution
    https://www.alchemists.io/articles/ruby_function_composition
    Input

    View full-size slide

  182. Transactable
    include Dry::Monads[:result]
    url = "https://xkcd.com"
    case Pinger.new.call(url)
    in Success(message) then puts "Success: #{message}"
    in Failure(error) then puts "Site is down or invalid. Reason: #{error}"
    end
    Execution
    https://www.alchemists.io/articles/ruby_function_composition
    Transaction

    View full-size slide

  183. Transactable
    include Dry::Monads[:result]
    url = "https://xkcd.com"
    case Pinger.new.call(url)
    in Success(message) then puts "Success: #{message}"
    in Failure(error) then puts "Site is down or invalid. Reason: #{error}"
    end
    Execution
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  184. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  185. Transactable
    Checking: https://xkcd.com...
    Success: Site is up!
    Input: https://xkcd.com
    Success
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  186. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  187. Transactable
    Checking: http://xkcd.com...
    Site is down or invalid. Reason: http://xkcd.com
    Input: http://xkcd.com
    Failure
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  188. Transactable
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  189. Transactable
    Checking: https://www.unknown.com...
    Site is down or invalid. Reason: Timed out after using the allocated 1 seconds.
    Input: https://www.unknown.com
    Failure
    https://www.alchemists.io/articles/ruby_function_composition

    View full-size slide

  190. Wait, Rewind

    View full-size slide

  191. Wait, Rewind

    View full-size slide

  192. Transactable
    https://www.alchemists.io/projects/transactable

    View full-size slide

  193. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable

    View full-size slide

  194. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable

    View full-size slide

  195. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable
    The URL (raw input).

    View full-size slide

  196. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable
    The URL (raw input).
    Print info to the console.

    View full-size slide

  197. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable
    The URL (raw input).
    Print info to the console.
    Check if the URL is secure.

    View full-size slide

  198. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable
    The URL (raw input).
    Print info to the console.
    Check if the URL is secure.
    Make the HTTP GET request.

    View full-size slide

  199. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable
    The URL (raw input).
    Print info to the console.
    Check if the URL is secure.
    Make the HTTP GET request.
    Ask the HTTP response for status.

    View full-size slide

  200. Transactable
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)
    https://www.alchemists.io/projects/transactable
    The URL (raw input).
    Print info to the console.
    Check if the URL is secure.
    Make the HTTP GET request.
    Ask the HTTP response for status.
    Report the HTTP status.

    View full-size slide

  201. Transactable
    https://www.alchemists.io/projects/transactable
    Pipe
    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)

    View full-size slide

  202. Transactable
    https://www.alchemists.io/projects/transactable
    Pipe
    method :get
    url
    tee
    check
    as
    method :report





    pipe url,
    tee(Kernel, :puts, "Checking: #{url}..."),
    check(/\Ahttps/, :match?),
    method(:get),
    as(:status),
    method(:report)

    View full-size slide

  203. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    View full-size slide

  204. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    Input

    View full-size slide

  205. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    Step
    Step
    Step
    Step
    Step

    View full-size slide

  206. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    Monad
    Monad
    Monad
    Monad
    Monad

    View full-size slide

  207. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    Pipe

    View full-size slide

  208. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    Pipe

    View full-size slide

  209. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    Pipe

    View full-size slide

  210. Architecture
    https://www.alchemists.io/projects/transactable
    method :get
    url
    tee
    check
    as
    method :report





    Pipe

    View full-size slide

  211. https://www.alchemists.io/projects/transactable

    View full-size slide

  212. https://www.alchemists.io/projects/transactable
    Transactable
    Dry Monads
    Composition

    View full-size slide

  213. Let's Connect!

    View full-size slide

  214. https://alchemists.io
    @[email protected]
    🌎
    Let's Connect!
    Alchemists

    View full-size slide