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. 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?
  2. 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
  3. 5 ? 1 2 8 3 4 6 7 A

    Quick Reasoning Test @AdamTornhill
  4. @AdamTornhill “The length of a test’s setup method is inversely

    related to the readability of the code under test.” —Adam’s Heuristic
  5. 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
  6. @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
  7. 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.
  8. … 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
  9. 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?)))
  10. … 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
  11. 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
  12. @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
  13. Immutability is Key @AdamTornhill Takeaways Think Pipelines - Functions and

    Architecture No Silver Bullet - Programming is still hard
  14. @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]