embracing clojure: a journey into clojure adoption

14
Embracing Clojure A journey into Clojure adoption LambdaCon 2015-3-28, Bologna, Italy Luca Grulla

Upload: luca-grulla

Post on 15-Jul-2015

2.701 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Embracing Clojure: a journey into Clojure adoption

Embracing ClojureA journey into Clojure adoption

LambdaCon

2015-3-28, Bologna, Italy

Luca Grulla

Page 2: Embracing Clojure: a journey into Clojure adoption

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

Page 3: Embracing Clojure: a journey into Clojure adoption

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

Page 4: Embracing Clojure: a journey into Clojure adoption

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

Page 5: Embracing Clojure: a journey into Clojure adoption

~$ lein new aggregator

Page 6: Embracing Clojure: a journey into Clojure adoption

Challenge #1: Emacs

Steep learning curve

Page 7: Embracing Clojure: a journey into Clojure adoption

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

Page 8: Embracing Clojure: a journey into Clojure adoption

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)

Page 9: Embracing Clojure: a journey into Clojure adoption

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)

Page 10: Embracing Clojure: a journey into Clojure adoption

Epiphany #2: function composition

(defn not?[nationality p] (not= nationality (:nationality p)))

(filter (partial not? "Italian") people)

(partial f arg1)

Page 11: Embracing Clojure: a journey into Clojure adoption

Epiphany #3: functions are first class citizens

Everything is geared toward functions creation and composition

Page 12: Embracing Clojure: a journey into Clojure adoption

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

Page 13: Embracing Clojure: a journey into Clojure adoption

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

Page 14: Embracing Clojure: a journey into Clojure adoption

@lucagrulla www.lucagrulla.it

Questions?

we’re hiring!! http://www.uswitch.com/careers/