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.

Embracing Clojure: a journey into Clojure adoption

4,096 views

Published on

What happens when a small team of very experienced developers with no real functional programming experience decides to use Clojure to run a core system architecture component?
This is the story of a 2 years journey of my team with Clojure, sharing learnings, epiphanies, success as well as some of the challenges we encountered.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Embracing Clojure: a journey into Clojure adoption

  1. 1. Embracing Clojure A journey into Clojure adoption LambdaCon 2015-3-28, Bologna, Italy Luca Grulla
  2. 2. Back in 2012 we had… • A new product idea • Lean team: 2 developers • both with 10+ years of experience • both polyglot • no Functional Programming experience
  3. 3. Product Architecture Website AggregatorJson { name: "Luca" claims: [] address: "42 Magic Road" abi: "123456"} [{"premium": "150", "brand": “foo"} {"premium":"180", "brand":"blah"}] xml xml xml xml xml insurer#1 insurer#4 insurer#2 insurer#3 insurer#5
  4. 4. Why Clojure? • The problem we had to solve was data transformation: FP was a pretty good match • Mature stack(JVM, repos, Java libraries) • Language with huge growth potentials • Strong Clojure support within the organisation
  5. 5. ~$ lein new aggregator
  6. 6. Challenge #1: Emacs Steep learning curve
  7. 7. Challenge #2: read LISP (def my-vector [{:val 8} {:val 33} {:val 42} {:val 13}]) (* (reduce + (map :val (filter(fn[y] (< (:val y) 20)) my-vector))) 2) ;;42
  8. 8. Epiphany #1: threading macro for local pipelines (->> my-vector (filter (fn[y] (< (:val y) 20))) (map :val) (reduce +) (* 2)) ;;42 (* (reduce + (map :val (filter(fn[y] (< (:val y) 20)) my-vector))) 2) ;;42 (->> x & forms)
  9. 9. Challenge #3: idiomatic Clojure (def people [{:name "Luca" :nationality “Italian"} {:name "Tim" :nationality “Canadian"} {:name "Davie" :nationality “British"} {:name "David" :nationality “Belgian"} {:name "Mike" :nationality "British"}]) (filter not-italian? people) (defn not-italian?[p] (not= "Italian" (:nationality p))) (filter (fn[p] (not= "Italian" (:nationality p))) people) (filter (fn[p] (not= "British" (:nationality p))) people)
  10. 10. Epiphany #2: function composition (defn not?[nationality p] (not= nationality (:nationality p))) (filter (partial not? "Italian") people) (partial f arg1)
  11. 11. Epiphany #3: functions are first class citizens Everything is geared toward functions creation and composition
  12. 12. Epiphany #4: parallelism made easy (def request-func [partner-1-func partner-2-func partner-3-func]) (pmap #(apply % []) request-func) ;;hardware bound(num of processors +2) (map #(future (apply % [])) request-func) ;;collection of futures clojure.core.async
  13. 13. tl;dr • If you are doing some sort of data transformation you should look at Clojure • Clojure code is terse and expressive • Mature ecosystem: JVM, repos, libraries • Personal growth: people are challenged by the new paradigm, solid CS concepts took back into the game • Business impact: functional composition + parallelism will give you a competitive advantage
  14. 14. @lucagrulla www.lucagrulla.it Questions? we’re hiring!! http://www.uswitch.com/careers/

×