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

Functional Programming in the Real World

Functional Programming in the Real World

Functional Programming is sold as a silver bullet. Yet most organizations lack real-world experience with the paradigm. It’s hard to adopt functional programming too since most public examples show small and isolated code snippets and it’s not clear how those pieces would fit together to form a system, a functional architecture. A real-world system also has to deal with non-functional side effects and the rapid feature growth of an evolving product. So how well does functional programming work in practice? What happens when you bet your company on a functional programming language? Will the hype transfers into productivity gains and cheaper maintenance?

Adam Tornhill

June 14, 2017
Tweet

More Decks by Adam Tornhill

Other Decks in Programming

Transcript

  1. @AdamTornhill
    FUNCTIONAL PROGRAMMING
    IN THE REAL WORLD
    http://www.empear.com/

    View full-size slide

  2. @AdamTornhill
    My Road To Functional Programming

    View full-size slide

  3. Clojure
    @AdamTornhill
    My Road To Functional Programming
    1980 1990 2000 2010 2015
    Assembly
    C
    Pascal
    C++
    Java
    TCL
    http://www.paulgraham.com/avg.html
    Erlang J?

    View full-size slide

  4. Less Code, More Features, More Fun
    @AdamTornhill
    Erlang
    Java
    Lines of Code

    View full-size slide

  5. The 60/60 Rule
    @AdamTornhill
    https://www.amazon.com/Facts-Fallacies-Software-Engineering-Robert/dp/0321117425/

    View full-size slide

  6. What’s Functional Programming?
    @AdamTornhill
    “If you ask 100 programmers for their definition,
    you'll likely receive 100 different answers”
    — Michael Fogus & Chris Houser
    Immutability
    Lambda Calculus Recursion
    Lazy Evaluation
    Category Theory
    Monads
    Pure Functions
    Referential Transparency
    Hindley–Milner type inference

    View full-size slide

  7. Immutable State
    @AdamTornhill
    i = 41;

    View full-size slide

  8. 5
    ?
    1 2
    8
    3 4
    6 7
    A Quick Reasoning Test
    @AdamTornhill

    View full-size slide

  9. @AdamTornhill
    Don’t Turn Your Code Into An IQ Test
    state
    Side effects
    Working memory tax

    View full-size slide

  10. IMMUTABILITY ALLOWS PROGRAMS TO
    SCALE IN COGNITIVE TERMS
    @AdamTornhill

    View full-size slide

  11. TDD: A Diminishing Return in FP
    @AdamTornhill

    View full-size slide

  12. REPL interactions -> soon to
    become unit tests
    REPL Driven Development
    @AdamTornhill

    View full-size slide

  13. The Perils Of Test Setup
    @AdamTornhill Code from https://github.com/aspnet/Mvc

    View full-size slide

  14. @AdamTornhill
    “The length of a test’s setup method
    is inversely related to the readability
    of the code under test.”
    —Adam’s Heuristic

    View full-size slide

  15. Unit Tests With Immutable State
    0 (ZERO) SETUP METHODS

    View full-size slide

  16. Threading Macros
    @AdamTornhill
    (defn costs-by-file

    [costs file-name->ticket]

    (->> costs
    (map (partial assign-to-files file-name->ticket))
    (filter passes-thresholds?)
    (reduce by-file-name)))
    Readability and Code Evolution

    View full-size slide

  17. @AdamTornhill
    (defn costs-by-file

    [costs file-name->ticket]

    (->> costs
    (map (partial assign-to-files file-name->ticket))
    (filter passes-thresholds?)
    (reduce by-file-name)))
    Performance And Lazy Evaluation
    lazy
    lazy

    View full-size slide

  18. In Introductory Presentations
    …In The Real World
    @AdamTornhill
    Functional Programming

    View full-size slide

  19. A Production System in FP
    @AdamTornhill
    https://codescene.io/

    View full-size slide

  20. A Production Systems in FP
    @AdamTornhill
    https://codescene.io/
    CodeScene on-premises
    Two

    View full-size slide

  21. Analysing Android
    @AdamTornhill
    Analysis of https://github.com/android/platform_frameworks_base

    View full-size slide

  22. @AdamTornhill
    docs
    core
    services
    packages
    tools
    media

    View full-size slide

  23. @AdamTornhill

    View full-size slide

  24. @AdamTornhill

    View full-size slide

  25. @AdamTornhill

    View full-size slide

  26. @AdamTornhill

    View full-size slide

  27. The Need For Concurrency
    @AdamTornhill
    .
    .
    .

    View full-size slide

  28. Concurrency Made Easy
    @AdamTornhill
    Possible
    (map complexity-trend files)
    (pmap complexity-trend files)
    Concurrency Exception!

    View full-size slide

  29. Functional Architecture
    @AdamTornhill
    MACRO LEVEL: same difference
    SUB-SYSTEM LEVEL: more freedom
    ISOLATE SIDE EFFECTS
    Side effects should be clear and kept to a thin
    layer at the edge of your system.

    View full-size slide


  30. Social
    Architectural Pattern: Pipes And Filters
    Input Sources
    Git
    JIRA
    Teams
    Transformations
    Time
    Users
    Files
    Analyses
    Hotspots
    Effort
    Pattern Detectors
    Risk
    Neural Nets

    Git Time Users Files Hotspots Early Warnings
    Run-time behaviour
    Result, purely functional, no side-effects

    View full-size slide

  31. Remember The Pipeline Style?
    @AdamTornhill
    (defn costs-by-file

    [costs file-name->ticket]

    (->> costs
    (map (partial assign-to-files file-name->ticket))
    (reduce by-file-name)
    (filter passes-thresholds?)))

    View full-size slide


  32. Social
    Architectural Pattern: Pipes And Filters
    Input Sources
    Git
    JIRA
    Teams
    Transformations
    Time
    Users
    Files
    Analyses
    Hotspots
    Effort
    Pattern Detectors
    Risk
    Neural Nets

    Git Time Users Files Hotspots Early Warnings
    Run-time behaviour
    Result, purely functional, no side-effects

    View full-size slide

  33. Beyond Myths: A Real-World Dirty REST API
    Domain specific language for
    describing routes
    Side-effects:
    1. Read from DB
    2. Fire-off a pipeline of business logic
    3. Write the results to DB, reply

    View full-size slide

  34. Finally A Silver Bullet?
    @AdamTornhill

    View full-size slide

  35. LAZY EVALUATION IS GREAT
    @AdamTornhill
    …EXCEPT FOR WHEN IT’S NOT

    View full-size slide

  36. @AdamTornhill
    (defn costs-by-file

    [costs file-name->ticket]

    (->> costs
    (map (partial assign-to-files file-name->ticket))
    (reduce by-file-name)
    (filter passes-thresholds?)))
    The code we write:
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.core$apply.invoke (core.clj:641)
    codescene.analysis.diagnostics$trace_ns$fn__9583
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.core$apply.invoke (core.clj:641)
    codescene.analysis.diagnostics$trace_ns$fn__9583
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.core$apply.invoke (core.clj:641)
    codescene.analysis.diagnostics$trace_ns$fn__9583
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.core$apply.invoke (core.clj:641)
    codescene.analysis.diagnostics$trace_ns$fn__9583
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.core$apply.invoke (core.clj:641)
    codescene.analysis.diagnostics$trace_ns$fn__9583
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invokeStatic (core.clj:646)
    The exception we get
    Clojure Specific: The Semantic Gap

    View full-size slide

  37. Java — The Assembly Language of the JVM
    @AdamTornhill
    Dealing With Performance Issues

    View full-size slide

  38. Immutability is Key
    @AdamTornhill
    Takeaways
    Think Pipelines - Functions and Architecture
    No Silver Bullet - Programming is still hard

    View full-size slide

  39. @AdamTornhill
    Beyond Functional Programming
    http://www.adamtornhill.com/articles/jlang/beyondfunctional.html
    The Day I Parsed A Monster
    http://www.empear.com/blog/parse-a-monster/
    Lisp for the Web (free)
    https://leanpub.com/lispweb
    Try CodeScene
    https://codescene.io/
    [email protected]

    View full-size slide