Successfully reported this slideshow.
Your SlideShare is downloading. ×

Javaslang Talk @ Javaland 2017

Ad

#JavalandJavaslang @koenighotze
java
slang
The Monad strikes back

Ad

#JavalandJavaslang @koenighotze
David Schmitz - koenighotze
Senacor Technologies
Principal Architect
Programmer!
That’s me...

Ad

#JavalandJavaslang @koenighotze
What’s in it for you?
Functional programming is hip
How Javaslang helped us
Live Code - OM...

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Upcoming SlideShare
Javaslang @ Devoxx
Javaslang @ Devoxx
Loading in …3
×

Check these out next

1 of 120 Ad
1 of 120 Ad

More Related Content

Javaslang Talk @ Javaland 2017

  1. 1. #JavalandJavaslang @koenighotze java slang The Monad strikes back
  2. 2. #JavalandJavaslang @koenighotze David Schmitz - koenighotze Senacor Technologies Principal Architect Programmer! That’s me coding Scala
  3. 3. #JavalandJavaslang @koenighotze What’s in it for you? Functional programming is hip How Javaslang helped us Live Code - OMG! Because of Beamer
  4. 4. #JavalandJavaslang @koenighotze Functors, applicatives, monads stay home
  5. 5. #JavalandJavaslang @koenighotze Code that is easier to reason about
  6. 6. #JavalandJavaslang @koenighotze Side-effects are evil try { int i = 1/0; } catch (Throwable t) { … } Exceptions are goto-statements :(
  7. 7. #JavalandJavaslang @koenighotze Referential Transparency Math.random(); Math.max(1, 2); Math.random(); Math.max(1, 2); Pure functions are a Good ThingTm :(
  8. 8. #JavalandJavaslang @koenighotze Thinking in values Immutability Performance Safety
  9. 9. #JavalandJavaslang @koenighotze In a nutshell, think about “what to code“ not “how to code”
  10. 10. #JavalandJavaslang @koenighotze Enter java Eight (a) -> a + 2 list.stream().filter… Excitement…
  11. 11. #JavalandJavaslang @koenighotze Try filtering all invalid users from a list of users
  12. 12. #JavalandJavaslang @koenighotze Excitement?…until users.stream() .filter(user -> { try { return user.validate(); } catch (Exception ex) { return false; }}) .collect(Collectors.toList());
  13. 13. #JavalandJavaslang @koenighotze import static javaslang.API.*;
  14. 14. #JavalandJavaslang @koenighotze What we’ll cover Immutable collections Some functional sugar Pattern matching Property based testing Circuit breaker
  15. 15. #JavalandJavaslang @koenighotze Before we get to the details… Let’s fix that ugly code
  16. 16. #JavalandJavaslang @koenighotze Fixing Things…. users.stream() .filter(user -> { try { return user.validate(); } catch (Exception ex) { return false; }}) .collect(Collectors.toList());
  17. 17. #JavalandJavaslang @koenighotze Functional collections List.ofAll(users) .filter(user -> { try { return user.validate(); } catch (Exception ex) { return false; }}) .collect(Collectors.toList());
  18. 18. #JavalandJavaslang @koenighotze No need for Collectors List.ofAll(users) .filter(user -> { try { return user.validate(); } catch (Exception ex) { return false; }}) .collect(Collectors.toList());
  19. 19. #JavalandJavaslang @koenighotze No need for Collectors List.ofAll(users) .filter(user -> { try { return user.validate(); } catch (Exception ex) { return false; }}); .collect(Collectors.toLis t());
  20. 20. #JavalandJavaslang @koenighotze Wrapping Exceptions List.ofAll(users) .filter(user -> { try { return user.validate(); } catch (Exception ex) { return false; }}); .collect(Collectors.toLis t());
  21. 21. #JavalandJavaslang @koenighotze Wrapping Exceptions List.ofAll(users) .filter(user -> Try.of(user::validateAddress) .getOrElse(false) ); } catch (IllegalStateException ex) { return ); .collect(Collectors.toList();
  22. 22. #JavalandJavaslang @koenighotze List.ofAll(users) List.filter(user -> Try.of(user::validateAddress) .getOrElse(false));
  23. 23. #JavalandJavaslang @koenighotze immutable Collections
  24. 24. #JavalandJavaslang @koenighotze Mutable Collections are Evil Returning void == Side-Effect! interface Collection<E> { … void clear(); } interface Collection<E> { … void clear(); }
  25. 25. #JavalandJavaslang @koenighotze java.util.Collections Collections .unmodifiableList(list); .add(“💥”)
  26. 26. #JavalandJavaslang @koenighotze java.util.Collections Collections .unmodifiableList(list) .add(“💥”);
  27. 27. #JavalandJavaslang @koenighotzePainting by Gustav Courbet java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection .add(Collections.java:1055) at java.util.stream.AbstractPipeline.<init> (AbstractPipeline.java:203) at java.util.stream.ReferencePipeline.<init> (ReferencePipeline.java:94)
  28. 28. #JavalandJavaslang @koenighotze Javaslang Collections https://cdn.infoq.com/statics_s2_20170314-0434/resource/news/2016/11/the-road-to-javaslang-3/en/resources/1infoq-version2.0-library.png
  29. 29. #JavalandJavaslang @koenighotze Functional data structures Immutable Referentially transparent Persistent
  30. 30. #JavalandJavaslang @koenighotze heroes = List.of("Han", "Luke") Cons@661 “Han” T Cons@666 “Luke” () heroes Effectively immutable
  31. 31. #JavalandJavaslang @koenighotze Cons@661 “Han” T Cons@666 “Luke” () heroes Cons@662 “Ben” Tmore more = heroes.prepend("Ben") Effectively immutable
  32. 32. #JavalandJavaslang @koenighotze droids = TreeSet.of( "C3PO", "R2D2", "K2SO" ) Node@676 Node@679 Node@681“K2SO” () ()“C3PO” () ()“R2D2” Effectively immutable
  33. 33. #JavalandJavaslang @koenighotze droids.add("Chopper"); Effectively immutable
  34. 34. #JavalandJavaslang @koenighotze Node@689 Node@691 () Node@694 () ()“Chopper” Node@676 Node@679 Node@681“K2SO” () ()“C3PO” () ()“R2D2” Effectively immutable
  35. 35. #JavalandJavaslang @koenighotze old == new Checking for updates?
  36. 36. #JavalandJavaslang @koenighotze Streams are glorified iterators Stream<String> jdk = Stream.of("a", “B"); jdk.map(String::toUpperCase); jdk.map(String::toLowerCase);
  37. 37. #JavalandJavaslang @koenighotzePainting by Gustav Courbet java.lang.IllegalStateException: stream has already been operated upon or closed at java.util.stream.AbstractPipeline.<init> (AbstractPipeline.java:203) at java.util.stream.ReferencePipeline.<init> (ReferencePipeline.java:94)
  38. 38. #JavalandJavaslang @koenighotze Stream<String> slang = Stream.of("a", "B"); slang.map(String::toUpperCase); // “A”,“B” slang.map(String::toLowerCase); // “a”,“b” Javaslang streams
  39. 39. #JavalandJavaslang @koenighotze Javaslang Streams Stream<String> slang = Stream.of("a", "B"); slang.map(String::toUpperCase) .take(2); slang.map(String::toLowerCase) .take(2);
  40. 40. #JavalandJavaslang @koenighotze Javaslang Streams Stream<String> slang = Stream.of("a", "B"); slang.map(String::toUpperCase) .take(2);// “A”,“B” slang.map(String::toLowerCase) .take(2);// “a”,“b”
  41. 41. #JavalandJavaslang @koenighotze Better performance Less unexpected behaviour
  42. 42. #Devoxx #Javaslang @koenighotze functional Sugar
  43. 43. #JavalandJavaslang @koenighotze find a user and, if an address is available, fetch the user’s street
  44. 44. #JavalandJavaslang @koenighotze Cascading Pile of Shame User user = repo.findOne("id"); if (user != null) { Address address = user.getAddress(); if (null != address) { return address.getStreet(); } }
  45. 45. #JavalandJavaslang @koenighotze optional? Optional<User> opt = Optional.ofNullable(user); if (optional.isPresent()) { User user = optional.get(); }
  46. 46. #JavalandJavaslang @koenighotze And now, young coder... you will die.
  47. 47. #JavalandJavaslang @koenighotze
  48. 48. #JavalandJavaslang @koenighotze map or flatmap There is no isPresent()
  49. 49. #JavalandJavaslang @koenighotze optional or option? Optional
  50. 50. #JavalandJavaslang @koenighotze optional or option? Option Some None
  51. 51. #JavalandJavaslang @koenighotze optional or option? Option Some None Value Iterable
  52. 52. #JavalandJavaslang @koenighotze optional or option? Option Some None Value Iterable
  53. 53. #JavalandJavaslang @koenighotze optional or option? Option Some None Value Iterable Serializable
  54. 54. #JavalandJavaslang @koenighotze An option is like a Gift Box NoneSome
  55. 55. #JavalandJavaslang @koenighotze Map opens the Gift Box Map Some Some ( )->
  56. 56. #JavalandJavaslang @koenighotze nothing from nothing ( )-> Map None None
  57. 57. #JavalandJavaslang @koenighotze Fixing the Pile of Shame User user = repo.findOne("id"); if (user != null) { Address address = user.getAddress(); if (null != address) { return address.getStreet(); } }
  58. 58. #JavalandJavaslang @koenighotze option all the Things User user = repo.findOne("id"); if (user != null) { Address address = user.getAddress(); if (null != address) { return address.getStreet(); } }
  59. 59. #JavalandJavaslang @koenighotze option all the Things Option<User> user = repo.findOne("id"); if (user != null) { Address address = user.getAddress(); if (null != address) { return address.getStreet(); } }
  60. 60. #JavalandJavaslang @koenighotze option all the Things Option<User> user = repo.findOne("id"); if (user != null) { Address address = user.getAddress(); if (null != address) { return address.getStreet(); } }
  61. 61. #JavalandJavaslang @koenighotze option all the Things Option<User> user = repo.findOne("id"); user.flatMap(User::getAddress) Address address = user.getAddress(); if (null != address) { return address.getStreet(); } } Option<User> user = repo.findOne("id"); user.flatMap(User::getAddress) Address address = user.getAddress(); if (null != address) { return address.getStreet(); } } Option<Address> getAddress()
  62. 62. #JavalandJavaslang @koenighotze option all the Things Option<User> user = repo.findOne("id"); user.flatMap(User::getAddress) Address address = user.getAddress(); if (null != address) { return address.getStreet(); } }
  63. 63. #JavalandJavaslang @koenighotze option all the Things Option<User> user = repo.findOne("id"); user.flatMap(User::getAddress) Address address = user.getAddress(); .map(Address::getStreet) return address.getStreet(); } }
  64. 64. #JavalandJavaslang @koenighotze repo.findOne("id") .flatMap(User::getAddress) .map(Address::getStreet) .getOrElse("");
  65. 65. #JavalandJavaslang @koenighotze option.of(value) .map(nested code) == understandable story
  66. 66. #JavalandJavaslang @koenighotze working with legacy code
  67. 67. #JavalandJavaslang @koenighotze Nice validation Code public static String check(String iban){ if (validationMagic(iban)) { return iban; } throw new IllegalArgumentException(“Peng”); }
  68. 68. #JavalandJavaslang @koenighotze Awesome WTF Code String iban; try { iban = check(“AL47…”); } catch (IllegalArgumentException ex) { iban = ""; }
  69. 69. #JavalandJavaslang @koenighotze From Exceptions to options String iban = lift(Iban::check) .apply("AL47...") .getOrElse("");
  70. 70. #JavalandJavaslang @koenighotze From Exceptions to options String iban = lift(Iban::check) .apply("AL47...") .getOrElse("");
  71. 71. #JavalandJavaslang @koenighotze Wrapping Exceptions with Try Try.of(() -> stuffToDo())
  72. 72. #JavalandJavaslang @koenighotze Wrapping Exceptions with Try Failure Exception Success Result Try.of(() -> stuffToDo())
  73. 73. #JavalandJavaslang @koenighotze Exceptions to options with Try Try.of(() -> check("AL..")) .getOrElse("")
  74. 74. #JavalandJavaslang @koenighotze Exceptions to options with Try Try.of(() -> check("AL..")) .getOrElse("")
  75. 75. #JavalandJavaslang @koenighotze Lifting and Try-ing reduce exception handling clutter and side-effects
  76. 76. #JavalandJavaslang @koenighotze Structural Decomposition
  77. 77. #JavalandJavaslang @koenighotze (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=? ^_`{|}~-]+)*|"(?:[x01-x08x0bx0cx0e-x1fx21x23- x5bx5d-x7f]|[x01-x09x0bx0cx0e-x7f])*")@(?:(?: [a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a- z0-9-]*[a-z0-9])?|[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9] [0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a- z0-9-]*[a-z0-9]:(?:[x01-x08x0bx0cx0e-x1fx21- x5ax53-x7f]|[x01-x09x0bx0cx0e-x7f])+)]) Pattern Matching Basics
  78. 78. #JavalandJavaslang @koenighotze Pattern Matching Basics Match(expression) .of(cases)
  79. 79. #JavalandJavaslang @koenighotze Cases map patterns to function Case(pattern, function)
  80. 80. #JavalandJavaslang @koenighotze Example Patterns $() wildcard pattern $(“foo”) equals pattern isIn(“a”, “b”) conditional pattern
  81. 81. #JavalandJavaslang @koenighotze Classic HTTP Handling if (OK.equals(res.getStatusCode())) { return res.getBody(); } return emptyList();
  82. 82. #JavalandJavaslang @koenighotze HTTP Handling Fixed *Note: some type details missing Match(res.getStatusCode()) .of(
 Case($(OK), res.getBody()),
 Case($(), emptyList())
 );
  83. 83. #JavalandJavaslang @koenighotze Match(res.getStatusCode()) .of(
 Case($(OK), res.getBody()),
 Case($(), emptyList())
 ); HTTP Handling Fixed *Note: some type details missing OK or anything else
  84. 84. #JavalandJavaslang @koenighotze HTTP Handling Fixed *Note: some type details missing Match(res.getStatusCode()) .of(
 Case($(OK), res.getBody()),
 Case($(), emptyList())
 );
  85. 85. #JavalandJavaslang @koenighotze HTTP Handling Fixed *Note: some type details missing Match(res.getStatusCode()) .of(
 Case($(OK), res.getBody()),
 Case($(), emptyList())
 );
  86. 86. #JavalandJavaslang @koenighotze HTTP Handling Fixed Match(res.getStatusCode()) .of(
 Case($(OK), res.getBody()),
 Case($(), emptyList())
 ); *Note: some type details missing
  87. 87. #JavalandJavaslang @koenighotze Matching a Try public Try<…> fetchFromUrl(…) { … }
  88. 88. #JavalandJavaslang @koenighotze Matching a Try Match(fetchFromUrl(“…”)) .of( Case(Success($()), identity()), Case(Failure($()), emptyList()) );
  89. 89. #JavalandJavaslang @koenighotze Matching a Try Match(fetchFromUrl(“…”)) .of( Case(Success($()), identity()), Case(Failure($()), emptyList()) );
  90. 90. #JavalandJavaslang @koenighotze Matching a Try Match(fetchFromUrl(“…”)) .of( Case(Success($()), identity()), Case(Failure($()), emptyList()) );
  91. 91. #JavalandJavaslang @koenighotze Presto Match(fetchFromUrl(“…”)) .of( Case(Success($()), identity()), Case(Failure($()), emptyList()) );
  92. 92. #JavalandJavaslang @koenighotze Pattern matching replaces complex if- then-else sequences with clear expressions
  93. 93. #JavalandJavaslang @koenighotze property tEST
  94. 94. #JavalandJavaslang @koenighotze property Based - The idea Describe the arguments Describe the results Let the olde computer prove you wrong
  95. 95. #JavalandJavaslang @koenighotze Javaslang property test Property.def(“Add works") .forAll(Generated Data) .suchThat(Checked Function) .check() .assertIsSatisfied();
  96. 96. #JavalandJavaslang @koenighotze Javaslang property test Property.def(“Add works") .forAll(integer(), integer()) .suchThat( (a,b)-> calc.add(a, b) == a + b) .check() .assertIsSatisfied();
  97. 97. #JavalandJavaslang @koenighotze Running tests 2017-03-21 10:45:59.913 INFO 45701 --- FrameworkServlet '': initialization started 2017-03-21 10:45:59.925 INFO 45701 --- FrameworkServlet '': initialization completed in 12 ms Storing User@217b0952[username=rwxbeoigyesbeqqz,email=W`a@0c..-.--db-.T5-.2-g, Storing User@4e6280de[username=vptafghfwuwwrwall,email=sByP@6jLA4.J.1c..5h269O3-1M6-c6...-.-,,, Storing User@2fca282c[username=qmhkjdtvbtjzfciwcceqgzfznzkhhcokiyoipdefbr,email=Q96!@6.n8. Storing User@64d53f0d[publicId=e9d7a121-9f23-483a-828a-f9e3045fc297,username=unflrpvztxtmi... ... Storing User@1b10f60e[publicId=6f084c18-415c-42c4-b1a8-00c5c1fc9e67,username=xwhpdpjowirsmjym... Storing User@4b916cc2[publicId=a2b9db2c-0189-4fe8-843d-e709ef3886fa,username=yxdidpexnayyjpzo... Should not go boom: OK, passed 1000 tests in 3719 ms.
  98. 98. #JavalandJavaslang @koenighotze Failures Should not go boom: Falsified after 23 passed tests in 3005 ms. java.lang.AssertionError: Expected satisfied check result but was Falsified(…, sample = ( 풧 ꜏, 燤䠽뾌密ᵓ뫶খᄀ ꌎ ⬆鹮 라鄽뾮魨 붐맧놌 엍첮 䏨➰ìឧ寅罟 溌椡‫ﲡ‬셋欙밶ῴ‫ﯯ‬缲ꢶꇞ⌽ꪂ惗 쎂蘄펮뎷粻뵞?푠쏽쥎, fzqlbkljxhfrghllzcthvgqiglaabihkzgsqwgfcichamyonmayiewwsfwmw ntzvozqqydkqillhpyi, +g4@F.8yOkj.-....C6GUP..3.4.-..h- V74.E.-----2T.z97..3f1ZM6))
  99. 99. #JavalandJavaslang @koenighotze Why property Based tests? Declarative, infinit test cases Have you tested for all characters… …even for 💩? Have you tested usernames like… ౧ప唆⏑쀋䯰㨼ᮁ娤즶?搃蘸阁뺬ᡧ㫈葷㖒‫ܪ‬匘ᤫ䳴㻅 댇껓痯믶㙃銐璚풔랾ᄰ 䩰삀싲闆䩟嗀嗀侀
  100. 100. #JavalandJavaslang @koenighotze functional resilience
  101. 101. #JavalandJavaslang @koenighotze Circuit breaker one-o-one Consumer Backend
  102. 102. #JavalandJavaslang @koenighotze Fallback Resilience decorator Circuit breaker one-o-one Closed Open Half-Open Consumer
  103. 103. #JavalandJavaslang @koenighotze Resilience decorator Circuit breaker one-o-one Closed Open Half-Open Consumer Fallback
  104. 104. #JavalandJavaslang @koenighotze Fallback Resilience decorator Circuit breaker one-o-one Closed Open Half-Open Consumer
  105. 105. #JavalandJavaslang @koenighotze Fallback Resilience decorator Circuit breaker one-o-one Closed Open Half-Open Consumer
  106. 106. #JavalandJavaslang @koenighotze Resilience For J BackendConsumer Backend Service Resilience decorator Circuit Breaker Retry Cache
  107. 107. #JavalandJavaslang @koenighotze Option<…> fetchBoard(String id) { result = restTemplate.getForEntity(…); return Match(result.getStatusCode()) .option(…); } flakey functions
  108. 108. #JavalandJavaslang @koenighotze Option<…> fetchBoard(String id) { result = restTemplate.getForEntity(…); return Match(result.getStatusCode()) .option(…); } flakey functions
  109. 109. #JavalandJavaslang @koenighotze Decorators.ofCheckedFunction(db::fetchBoard) .withCircuitBreaker(circuitBreaker) .decorate(); Decorating a function
  110. 110. #JavalandJavaslang @koenighotze Try.of(() -> decorated.apply(stationId)) .getOrElse(Option.of(empty())) Functional resilience
  111. 111. #JavalandJavaslang @koenighotze final celebration
  112. 112. #JavalandJavaslang @koenighotze HashMap.of("Foo", "Bar", "Qux", "Baz") Tuple.of("Foo", 1) String help = TODO("Implement me") Javaslang offers much more
  113. 113. #JavalandJavaslang @koenighotze Javaslang offers much more
  114. 114. #JavalandJavaslang @koenighotze So, is this is the mother of all free lunches?
  115. 115. #JavalandJavaslang @koenighotze What are the drawbacks?
  116. 116. #JavalandJavaslang @koenighotze What are the drawbacks? count(Collection-libs) > count(Logging-libs)
  117. 117. #JavalandJavaslang @koenighotze What are the drawbacks? Option.of(foo) .map .filter .flatMap .map .flatMap .getOrElse(null) N O T a drawback!
  118. 118. #JavalandJavaslang @koenighotze Wrapping up Slick, stable, consistent API Object-functional advantages now Complex(?) Version 3 coming soon!
  119. 119. #JavalandJavaslang @koenighotze RESISTTHE TYRANNY OF THE COLLECTIONS FRAMEWORK JOIN THE RESISTANCE!
  120. 120. #JavalandJavaslang @koenighotze thank you david.schmitz at senacor.com

×