Pragmatist’s Guide to Functional Geekery

Pragmatist’s Guide to Functional Geekery

Basic functional concepts like immutable data, second-order functions, lambdas and function composition can already be found in the modern programmer’s toolkit.

During this talk you will learn about more advanced functional concepts and how they can solve real problems. I will talk about pattern matching, algebraic data types, functional abstractions, folding and property-based tests.

I will show you a practical example written using today’s Java functional constructs and build up from there. I will use only Java & Vavr, which can improve the code, make it more maintainable and testable.

6f6dc1b13fd3fe35d36db3adafcb0c8e?s=128

Michał Płachta

May 17, 2017
Tweet

Transcript

  1. @miciek Michał Płachta Pragmatist`s Guide to www.michalplachta.com Functional Geekery

  2. @miciek Let’s talk functional!

  3. @miciek

  4. @miciek Galactic Twitter, one week.

  5. @miciek

  6. @miciek Being functional... higher order functions immutable collections no reassignments

    functions immutable types
  7. @miciek Being functional... higher order functions -style immutable collections Guava

    Immutable Collections Java 8 Streams no reassignments Java final keyword functions Java 8 lambdas immutable types Lombok @Value
  8. @miciek Being functional... higher order functions -style built-in and more!

    immutable collections built-in no reassignments val keyword functions first class citizens immutable types built-in
  9. @miciek Being functional... higher order functions -style built-in immutable collections

    built-in no reassignments val keyword functions first class citizens immutable types built-in
  10. @miciek Bringing style to

  11. @miciek Being functional... higher order functions -style built-in and more!

    immutable collections built-in no reassignments Java final keyword functions built-in immutable types Lombok @Value
  12. @miciek Galactic Twitter, one week.

  13. @miciek

  14. @miciek

  15. @miciek

  16. @miciek

  17. @miciek Future<T>

  18. @miciek Future<T> finishes successfully with a result of type T

    fails with an exception
  19. @miciek @miciek

  20. @miciek

  21. @miciek Future.get is a blocking call!

  22. @miciek Citizen Future Future List <Citizen> Future map ??? DBClient::getFollowers

  23. @miciek Citizen Future Future List <Citizen> Future List <Citizen> Future

    map flatMap Citizen Future map Integer Future ???
  24. @miciek

  25. @miciek Future.forEach doesn’t block! :)

  26. @miciek io.vavr.collection.HashMap Option<T> can be Some<T> when value is present

    can be None when value is not present
  27. @miciek

  28. @miciek polling every 200ms

  29. @miciek @miciek

  30. @miciek @miciek I have 0 followers. It’s not possible.

  31. @miciek @miciek

  32. @miciek Problem: treating 0 as “no value yet”

  33. @miciek Problem: treating 0 as “no value yet” Solution: explicit

    return type Option<T> can be Some<T> when value is present can be None when value is not present We should use types to model our assumptions!
  34. @miciek

  35. @miciek polling every 200ms when None is returned when Some(102)

    is returned
  36. @miciek @miciek

  37. @miciek @miciek I can’t check how many followers does Obi-wan

    Kenobi have!
  38. @miciek @miciek

  39. @miciek Problem: not handling Future failures java.lang.Exception: Bad Request: citizen

    with name Obi-wan Kenobi couldn't be found
  40. @miciek Problem: not handling Future failures Solution: explicit return type

    (again!) Try<T> can be Success<T> when computation succeeded can be Failure when computation failed We should use types to model our assumptions!
  41. @miciek io.vavr.concurrent.Future

  42. @miciek Pipelining potential failures

  43. @miciek polling every 200ms when None is returned when Some(Success(102))

    is returned when Some(Failure) is returned
  44. @miciek @miciek

  45. @miciek @miciek I am not happy with the return types

    you use in the application!
  46. @miciek @miciek

  47. @miciek @miciek Future<Option<Try<List<? extends Citizen>>>> I am not happy with

    the return types we use in the application!
  48. @miciek Problem: cryptic, complicated types Solution: Algebraic Data Types Sum<T>

    can be Something or can be SomethingDifferent We should use types to model our assumptions! can be SomethingElse or Product<T> consists of Something and SomethingElse
  49. @miciek Citizen can be Civilian or can be Stormtropper can

    be Rebel or Stormtrooper consists of String name and boolean isCloned can be Jedi or can be Sith or ADTs
  50. @miciek

  51. @miciek

  52. @miciek How to convert Try<Integer> into RemoteFollowersData?

  53. @miciek Pattern Matching

  54. @miciek

  55. @miciek

  56. @miciek @miciek

  57. @miciek @miciek Darth Vader has way too many followers! They

    are all clones!
  58. @miciek Clones should not count as followers!

  59. @miciek Let’s count followers! io.vavr.collections.Traversable

  60. @miciek Citizen any Civilian or any Stormtropper that is not

    cloned any Rebel or any Jedi or any Sith or Counting followers returns true if
  61. @miciek Pattern Matching to the rescue!

  62. @miciek

  63. @miciek @miciek

  64. @miciek @miciek I am not happy! Galactic Twitter is used

    for political purposes!
  65. @miciek Fear is the path to the Dark Side. Yoda

    Help me Obi-Wan Kenobi, you're my only hope! Princess Leia Use the Force, Luke. Obi-Wan Kenobi Very political! Not cool!
  66. @miciek Don’t delete, manipulate! Censorship module • Condition: If the

    tweet is pro Dark Side ◦ Manipulation: Add more Dark Side • If the tweet is pro Light Side ◦ Replace Force with Dark Side • If the tweet is a general wisdom ◦ Replace Force with Dark Side ◦ Add more Dark Side • If the tweet is pro Rebellion and is not a joke ◦ Hail the Empire • If the tweet is pro Empire and is a joke ◦ Trash the Rebellion • If the tweet is not pro Empire nor Rebellion ◦ Add Force and even more Force ◦ Make joke about it • If the tweet is pro empire ◦ Add more Dark Side • Always ◦ Sacrifice for the Empire
  67. @miciek No more than 2 manipulations! Censorship module initial filters

    • If the tweet is pro Dark Side ◦ Add more Dark Side • If the tweet is pro Light Side ◦ Replace Force with Dark Side • If the tweet is a general wisdom ◦ Replace Force with Dark Side ◦ Add more Dark Side • If the tweet is pro Rebellion and is not a joke ◦ Hail the Empire • If the tweet is pro Empire and is a joke ◦ Trash the Rebellion • If the tweet is not pro Empire nor Rebellion ◦ Add Force and even more Force ◦ Make joke about it • If the tweet is pro empire ◦ Add more Dark Side • Always ◦ Sacrifice for the Empire
  68. @miciek

  69. @miciek

  70. @miciek or

  71. @miciek

  72. @miciek Executing a List? CensorFilter Original Tweet Censored Tweet (tweet,filter)

    -> newTweet CensorFilter CensorFilter (tweet,filter) -> newTweet (tweet,filter) -> newTweet (tweet, filter) -> newTweet
  73. @miciek Executing a List of ints? 4 (0, 4) ->

    0 + 4 6 3 (4, 6) -> 4 + 6 (10, 3) -> 10 + 3 Initial = 0 Output = 13 (result, x) -> result + x
  74. @miciek Executing a List of ints? 4 (result, x) ->

    result + x 6 3 (result, x) -> result + x (result, x) -> result + x Initial = 0 io.vavr.collections.List Output = 13
  75. @miciek CensorFilter Original Tweet Censored Tweet applyFilter CensorFilter CensorFilter applyFilter

    applyFilter
  76. @miciek CensorFilter CensorStatus (Tweet, manipulations) CensorStatus (censored Tweet, manipulations) applyFilter

    CensorFilter CensorFilter applyFilter applyFilter
  77. @miciek

  78. @miciek Feature Switch!

  79. @miciek @miciek

  80. @miciek @miciek You don’t have any tests!

  81. @miciek We used types to model our assumptions!

  82. @miciek Standard Unit Tests

  83. @miciek Problem: writing tests by examples Solution: property-based tests We

    should test the properties!
  84. @miciek

  85. @miciek

  86. @miciek @miciek

  87. @miciek @miciek Starring Coffeehouse Programmer Darth Vader Luke Skywalker Uncle

    Bob
  88. @miciek @miciek Directed by Future type Option type Try type

    “monads”
  89. @miciek @miciek Special Effects Algebraic Data Types Pattern Matching Property-based

    tests
  90. @miciek @miciek github.com/miciek/galactic-twitter Screenplay Java vs Scala Web server in

    Akka HTTP Pattern Matching implementation RemoteData as a Functor Type class pattern “Pimp my type” pattern
  91. @miciek @miciek (Your) Next Episode Everything as Data

  92. @miciek Pragmatist`s Guide to Functional Geekery github.com/miciek/galactic-twitter ANY QUESTIONS? Michał

    Płachta www.michalplachta.com
  93. @miciek @miciek

  94. @miciek @miciek You don’t have clean code!

  95. @miciek

  96. @miciek Concern #1: represent state of db cache Concern #2:

    represent RemoteData as JSON
  97. @miciek Coupled concerns RemoteData RemoteData as JSON Response HTTP Server

  98. @miciek Type class pattern RemoteData RemoteData as JSON Response RemoteData

    JSON Response HTTP Server HTTP Server RemoteData Tweet type class type class members
  99. @miciek Pure values, no mess!

  100. @miciek But the server needs an instance of type class!

  101. @miciek Compiler will use them automatically!

  102. @miciek

  103. @miciek Decoupled concerns RemoteData RemoteData as JSON Response RemoteData JSON

    Response HTTP Server HTTP Server RemoteData Tweet type class type class members
  104. @miciek Future type lib lib* built-in Option type lib lib*

    built-in Try type lib lib* built-in ADTs lib built-in built-in Pattern Matching lib kind of* built-in Property tests lib lib lib * more: https://github.com/MarioAriasC/funKTionale https://kotlin.link/articles/Kotlin-for-Scala-Developers.html https://programmingideaswithjake.wordpress.com/2016/08/27/improved-pattern-matching-in-kotlin/ Everything as Data