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

Functional Programming Made Easy in JAVA & C#

Yoan
April 30, 2020

Functional Programming Made Easy in JAVA & C#

Let's demystify together what is Functional Programming (FP) !!!
We will deep dive into FP paradigms like monads, pure functions, high order functions, and much more.
We will share why and how to apply those in Object Oriented languages like java (with vavr) & C# (with language-ext).

We will demonstrate how to write Functional code that is:
* More robust
* Easier to read
* Easier to maintain

This session is built as a mix of theory and practice. You will be able to use your favorite IDE to practice through code katas.

To be able to practice, please clone one of the below repository on your machine before the event :
* Repo for java friends : https://github.com/ythirion/vavr-kata.git

Yoan

April 30, 2020
Tweet

More Decks by Yoan

Other Decks in Programming

Transcript

  1. @algrison
    @yot88
    FUNCTIONAL PROGRAMMING
    MADE EASY
    IN JAVA & C#
    SOFTWARE CRAFTSMANSHIP
    LUXEMBOURG
    30 April at 5PM on ZOOM Free registration : HTTPS://BIT.LY/2RMKPFD

    View full-size slide

  2. WHO ARE WE ?
    YOAN THIRION
    Agile/craft coach freelance
    Software craftsman
    yoan-thirion.com
    ALEXANDRE GRISON
    Tech Lead, Coach, Solutions Architect,
    Software Craftsman at BIL
    Loves #Clojure
    grison.me

    View full-size slide

  3. @algrison
    @yot88

    View full-size slide

  4. @algrison
    @yot88
    FUNCTIONAL PROGRAMMING
    IS ALL ABOUT FUNCTIONS
    Lazy evaluation
    Pure functions (no side effect) Lambda functions (anonymous)
    Higher order functions Composition
    Closures
    (returning functions from functions)
    Currying & partial application
    Immutability
    Pattern matching
    Recursion

    View full-size slide

  5. @algrison
    @yot88
    PURE FUNCTIONS
    Pure functions don’t refer to any global state.
    The same inputs will always get the same output.
    Combined with immutable data types this means you can be
    sure the same inputs will give the same outputs.

    View full-size slide

  6. CONTEXT
    Source : http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html#just-what-is-a-functor,-really?
    Here’s a simple value And we know how to apply a function to this value:
    Let’s extend this by saying that any value can be
    in a context.
    For now you can think of a context as a box
    that you can put a value in
    Now when you apply a function to this value, you'll get different
    results depending on the context.
    This is the idea that Functors, Applicatives, Monads, Arrows etc are
    all based on.
    The Maybe data type defines two related contexts

    View full-size slide

  7. FUNCTORS
    A functor is any type that defines how map works.
    When a value is wrapped in a box, you can’t apply a normal function to it
    This is where map comes in! map knows how to apply functions to values that are wrapped in a box.

    View full-size slide

  8. FUNCTORS
    Here’s what is happening behind the scenes when we write
    Here’s what is happening behind the scenes when we try to map a function on an empty box

    View full-size slide

  9. FUNCTORS
    What happens when you apply a function to a list?
    lists are functors too

    View full-size slide

  10. FUNCTORS
    What happens when you apply a function to another function?
    When you use map on a function, you're just doing function composition!
    functions are also functors
    In Java with vavr map is called
    compose or andThen
    In C# with language-ext is called
    Compose

    View full-size slide

  11. APPLICATIVES
    Applicatives are like functors, except that not only the value is being wrapped in a
    context, but the function to apply to it also !

    View full-size slide

  12. MONADS
    Functors apply a function to a
    wrapped value
    Monads apply a function that takes a value and returns a wrapped value.
    Applicatives apply a wrapped function to a
    wrapped value

    View full-size slide

  13. MONADS
    What if we feed it with a
    wrapped value?
    This is where bind also called flatMap or chain comes in!
    If you pass in Nothing it’s even simpler

    View full-size slide

  14. MONADS
    We can chain calls to bind

    View full-size slide

  15. MONADS by example
    Another example: user types a path then we
    want to load the file content and display it

    View full-size slide

  16. @algrison
    @yot88
    FP
    IN JAVA / C#

    View full-size slide

  17. @algrison
    @yot88
    FP in Java / C#
    Already a lot of things in :
    With the Stream API : since Java 8
    LinQ : since .NET 3.5 (2007)
    Some cool new features in the latest versions of the languages.

    View full-size slide

  18. @algrison
    @yot88
    C# 8
    Pattern matching
    Record types in 8.x
    Immutable data types
    Free equality
    Easier pure functions

    View full-size slide

  19. @algrison
    @yot88
    2 LIBS TO
    RESCUE US

    View full-size slide

  20. @algrison
    @yot88
    Vavr is an object-functional language extension to Java,
    aiming at reducing lines of code and increase code quality.
    It provides persistent collections, functional abstractions
    for error handling, concurrent programming, and much more.
    Vavr fuses the power of object-oriented programming with the elegance and
    robustness of FP.
    Including a feature-rich, immutable, persistent collection library
    that smoothly integrates with Java's standard collections.
    We’re using it at BIL in a lot of µServices
    Integration with Spring Data & Jackson
    It is awesome
    This library uses and abuses the features of C# to provide a functional-
    programming 'base class library' that, if you squint, can look like
    extensions to the language itself.
    The desire here is to make programming in C# much more reliable and
    to make the engineer's inertia flow in the direction of declarative and
    functional code rather than imperative.
    https://github.com/vavr-io/vavr https://github.com/louthy/language-ext

    View full-size slide

  21. @algrison
    @yot88
    Maven

    io.vavr
    vavr
    0.10.2

    Gradle
    compile group: 'io.vavr', name: 'vavr', version: '0.10.2'
    Nuget
    Lombok for C#

    View full-size slide

  22. @algrison
    @yot88
    Monads (io.vavr.control):
    λ Option
    λ Either
    λ Try
    λ Validation
    APIs (io.vavr):
    λ Tuples (0 -> 8)
    λ Functions (0 -> 8)
    λ CheckedFunctions (0 -> 8)

    View full-size slide

  23. @algrison
    @yot88
    978-0521663502
    Purely functional collections (io.vavr.collection):

    View full-size slide

  24. @algrison
    @yot88
    Performance characteristics of Vavr Collections:

    View full-size slide

  25. @algrison
    @yot88
    MAIN FEATURES
    Immutable collections
    Useful monads
    Records
    Validation

    View full-size slide

  26. @algrison
    @yot88
    ONE MORE THING
    No more out parameters
    LINQ mapping

    View full-size slide

  27. @algrison
    @yot88
    PARTIAL APPLICATION
    Partial application allows us to create new function from an existing
    one by setting some arguments.

    View full-size slide

  28. @algrison
    @yot88
    CURRYING
    Currying is the same as converting a function that takes n arguments into n
    functions taking a single argument each.
    F(x, y, z) = z(x(y))
    Curried: F(x, y, z) = F(y) { F(z) { F(x) } }
    To get the full application: F(x)(y)(z)

    View full-size slide

  29. @algrison
    @yot88
    MEMOIZATION
    Memoization is some kind of caching
    if you memoize a function, it will be only executed once for a specific input

    View full-size slide

  30. @algrison
    @yot88
    OPTION
    Option is a monadic container with additions
    Represents an optional value : None / Some(value)
    map, flatMap, filter, peek, … Map, Bind, Filter, Do, …

    View full-size slide

  31. @algrison
    @yot88
    TRY
    Try is a monadic container which represents a computation that may
    either throw an exception or successfully completes
    map, flatMap, filter, mapTry, peek, recover,
    onFailure, onSuccess, …
    Map, Bind, Filter, Do, Match, IfFail, IfSucc, …

    View full-size slide

  32. @algrison
    @yot88
    HANDS ON :
    LET’S WRITE CODE

    View full-size slide

  33. @algrison
    @yot88
    BEFORE WE START
    One namespace to rule them all
    using static LanguageExt.Prelude;

    View full-size slide

  34. @algrison
    @yot88
    HOW TO ?
    Clone the repository in your favorite language :
    Java : https://github.com/ythirion/vavr-kata.git
    C# : https://github.com/ythirion/language-ext-kata.git
    Let’s start with (stay on master branch)
    OptionExercises
    TryExercises
    RealLifeExample
    Java pre-requesite :
    Install lombok plugin here

    View full-size slide

  35. REAL LIFE EXAMPLE
    Imperative, not safe, redundant checks, …

    View full-size slide

  36. REAL LIFE EXAMPLE
    Try, use a context, chain calls -> pipeline

    View full-size slide

  37. @algrison
    @yot88
    await REAL LIFE EXAMPLE

    View full-size slide

  38. @algrison
    @yot88
    WHAT ABOUT
    PERFORMANCES ?

    View full-size slide

  39. @algrison
    @yot88
    Generate fake users by using Bogus
    Map data with LINQ
    Map data with Language-Ext
    https://github.com/ythirion/fp-cs-benchmark C#

    View full-size slide

  40. @algrison
    @yot88
    With 100 Users
    With 10_000 Users
    3.5 x faster with LINQ
    2.94 x faster with LINQ
    C#

    View full-size slide

  41. @algrison
    @yot88
    Generate fake users at startup
    Map data with Java Stream API
    Map data with Vavr (directly from Spring Data)
    https://github.com/agrison/fp-java-benchmark Java

    View full-size slide

  42. 5 000 requests with 100 Users
    Similar performance
    Finished 5000 requests
    Concurrency Level: 100
    Time taken for tests: 4.931 seconds
    Complete requests: 5000
    Failed requests: 0
    Requests per second: 1014.05 [#/sec] (mean)
    Time per request: 98.614 [ms] (mean)
    Time per request: 0.986 [ms] (mean, across all concurrent requests)
    Transfer rate: 6834.96 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 1.2 0 12
    Processing: 9 97 14.3 98 193
    Waiting: 9 97 14.3 98 193
    Total: 9 98 13.8 98 193
    Percentage of the requests served within a certain time (ms)
    50% 98
    66% 99
    75% 99
    80% 100
    90% 102
    95% 103
    98% 105
    99% 107
    100% 193 (longest request)
    Java
    Finished 5000 requests
    Concurrency Level: 100
    Time taken for tests: 4.889 seconds
    Complete requests: 5000
    Failed requests: 0
    Requests per second: 1022.66 [#/sec] (mean)
    Time per request: 97.784 [ms] (mean)
    Time per request: 0.978 [ms] (mean, across all concurrent requests)
    Transfer rate: 6893.00 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 1.1 0 12
    Processing: 8 96 15.0 97 188
    Waiting: 8 96 15.0 97 188
    Total: 9 97 14.6 97 188
    Percentage of the requests served within a certain time (ms)
    50% 97
    66% 98
    75% 99
    80% 99
    90% 100
    95% 100
    98% 101
    99% 182
    100% 188 (longest request)
    Vavr
    Finished 5000 requests
    Concurrency Level: 100
    Time taken for tests: 7.510 seconds
    Complete requests: 5000
    Failed requests: 0
    Requests per second: 665.76 [#/sec] (mean)
    Time per request: 150.205 [ms] (mean)
    Time per request: 1.502 [ms] (mean, across all concurrent requests)
    Transfer rate: 0.00 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 0.0 0 0
    Processing: 1 1 3.8 1 52
    Waiting: 0 0 0.0 0 0
    Total: 1 1 3.8 1 52
    Percentage of the requests served within a certain time (ms)
    50% 1
    66% 1
    75% 1
    80% 1
    90% 1
    95% 2
    98% 23
    99% 26
    100% 52 (longest request)
    Linq
    Finished 5000 requests
    Concurrency Level: 100
    Time taken for tests: 6.928 seconds
    Complete requests: 5000
    Failed requests: 0
    Requests per second: 721.67 [#/sec] (mean)
    Time per request: 138.567 [ms] (mean)
    Time per request: 1.386 [ms] (mean, across all concurrent requests)
    Transfer rate: 0.00 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 0.0 0 1
    Processing: 1 1 3.3 1 49
    Waiting: 0 0 0.0 0 0
    Total: 1 1 3.3 1 49
    Percentage of the requests served within a certain time (ms)
    50% 1
    66% 1
    75% 1
    80% 1
    90% 1
    95% 2
    98% 3
    99% 26
    100% 49 (longest request)
    Lang-ext
    ab -c 100 -n 5000 -r localhost:port/path

    View full-size slide

  43. 10 000 requests with 1 000 Users
    Similar performance
    Finished 10000 requests
    Concurrency Level: 1000
    Time taken for tests: 9.942 seconds
    Complete requests: 10000
    Failed requests: 0
    Requests per second: 1005.87 [#/sec] (mean)
    Time per request: 994.162 [ms] (mean)
    Time per request: 0.994 [ms] (mean, across all concurrent requests)
    Transfer rate: 6779.81 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 9 27.3 0 130
    Processing: 36 931 173.1 979 1183
    Waiting: 36 931 173.1 979 1182
    Total: 137 940 147.5 979 1183
    Percentage of the requests served within a certain time (ms)
    50% 979
    66% 982
    75% 986
    80% 988
    90% 991
    95% 993
    98% 995
    99% 1004
    100% 1183 (longest request)
    Java
    Finished 10000 requests
    Concurrency Level: 1000
    Time taken for tests: 9.898 seconds
    Complete requests: 10000
    Failed requests: 0
    Requests per second: 1010.31 [#/sec] (mean)
    Time per request: 989.795 [ms] (mean)
    Time per request: 0.990 [ms] (mean, across all concurrent requests)
    Transfer rate: 6809.72 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 8 25.5 0 122
    Processing: 37 928 175.4 979 1352
    Waiting: 31 928 175.5 978 1352
    Total: 142 936 151.0 979 1352
    Percentage of the requests served within a certain time (ms)
    50% 979
    66% 980
    75% 981
    80% 982
    90% 983
    95% 985
    98% 986
    99% 1156
    100% 1352 (longest request)
    Vavr
    Finished 10000 requests
    Concurrency Level: 1000
    Time taken for tests: 16.666 seconds
    Complete requests: 10000
    Failed requests: 0
    Requests per second: 600.04 [#/sec] (mean)
    Time per request: 1666.564 [ms] (mean)
    Time per request: 1.667 [ms] (mean, across all concurrent requests)
    Transfer rate: 0.00 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 15.1 0 1088
    Processing: 1 1 3.7 1 100
    Waiting: 0 0 0.0 0 0
    Total: 1 2 15.6 1 1090
    Percentage of the requests served within a certain time (ms)
    50% 1
    66% 1
    75% 1
    80% 1
    90% 1
    95% 2
    98% 4
    99% 25
    100% 1090 (longest request)
    Finished 10000 requests
    Concurrency Level: 1000
    Time taken for tests: 16.827 seconds
    Complete requests: 10000
    Failed requests: 0
    Requests per second: 594.27 [#/sec] (mean)
    Time per request: 1682.738 [ms] (mean)
    Time per request: 1.683 [ms] (mean, across all concurrent requests)
    Transfer rate: 0.00 [Kbytes/sec] received
    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 18.6 0 1081
    Processing: 1 1 3.4 1 88
    Waiting: 0 0 0.0 0 0
    Total: 1 2 18.9 1 1084
    Percentage of the requests served within a certain time (ms)
    50% 1
    66% 1
    75% 1
    80% 1
    90% 1
    95% 2
    98% 3
    99% 25
    100% 1084 (longest request)
    ab -c 1000 -n 10000 -r localhost:port/path
    Linq Lang-ext

    View full-size slide

  44. @algrison
    @yot88
    WHAT DO YOU
    THINK ABOUT IT ?

    View full-size slide

  45. How & why we use it @BIL
    In µServices & batches.
    To make code:
    safer
    implicit
    less verbose

    View full-size slide

  46. @algrison
    @yot88
    TO GO FURTHER
    • Functional Core, Imperative shell
    • You can play with true FP languages on JVM or .NET
    F# on .NET
    Clojure, Kotlin, Scala
    Scott Wlaschin
    F# guru
    Paul Louth
    lang-ext
    Rich Hickey
    Clojure yoda
    Daniel Dietrich
    Vavr

    View full-size slide

  47. Option.of(“THANK YOU”)
    YOAN THIRION
    Agile/craft coach freelance
    Software craftsman
    yoan-thirion.com
    ALEXANDRE GRISON
    Tech Lead, Coach, Solutions Architect,
    Software Craftsman at BIL
    Loves #Clojure
    grison.me

    View full-size slide