Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Javaslang Talk @ Javaland 2017

494 views

Published on

Javaslang Demo @ Javaland 2017

Published in: Technology
  • Be the first to comment

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

×