Your SlideShare is downloading. ×
0
A dive into Clojure     Carlo Sciolla, Product Lead @ Backbase                        A DIVE INTO CLOJURE | April 6, 2012 ...
Carlo Sciolla                                                                        Product Lead                         ...
Motivational                                                         a.k.a. the towel they forgot to bring                ...
Ive seen things you people wouldnt believe                        Programming languages evolved throughout half a century....
* Single inheritance                                            * [Almost] everything is an Object                        ...
A paradigm shift                                                                       f (x)                        As muc...
macro   let                                                                       ?                                       ...
“                 Lisp is worth learning for the                                                 profound enlightenment ex...
Open the parens                                                   to never look at programs the same way                  ...
(defn hello [name]                                     (println (str “Hello, ” name “!”)))                        Double r...
(defn hello [name]                                     (println (str “Hello, ” name “!”)))                                ...
user> (hello “World”)                                   (defn hello [name]                                     (println (s...
user> (hello “World”)                                   (defn hello [name]                                     (println (s...
user> (hello “World”)                                   (defn hello [name]                                     (println (s...
user> (hello “World”)                                   (defn hello [name]                                     (println “H...
user> (hello “World”)                                   Hello, World!                                   (defn hello [name]...
user> (hello “World”)                                   Hello, World!                                Read                 ...
Whatʼs in a seq                                by any other interface it wouldn’t smell the same                        A ...
clojure.core/seq                                      ([coll])                                        Returns a seq on the...
(seq          (1 "test" :odd true)) => (1 "test" :odd true)                                     (seq          [1 "test" :o...
(map identity [1 2 3 4]) ; (1 2 3 4)                                     (filter odd? ‘(1 2 3 4)) ; (1 3)                 ...
Immutability                                                       ‘cause Java beans give you gas                        A...
Horse horse = new Horse(14);                        horse.getPosition();                                    ??            ...
(let [x {:one 1}]                                       (assoc x :two 2)                                       (println x)...
(defn letter-count [string]                      (let [reduce-fn (fn [counts letter]                                      ...
user> (letter-count “Amsterdam”)                        Doing real work                        Immutability doesn’t get in...
user> (letter-count “Amsterdam”)                                   (reduce-fn {} A)                        Doing real work...
user> (letter-count “Amsterdam”)                                   (reduce-fn {} A)                                   (red...
user> (letter-count “Amsterdam”)                                   (reduce-fn {} A)                                   (red...
user> (letter-count “Amsterdam”)                                   (reduce-fn                     {} A)                   ...
user> (letter-count “Amsterdam”)                                   (reduce-fn                     {} A)                   ...
user> (letter-count “Amsterdam”)                                   (reduce-fn                     {} A)                   ...
user> (letter-count “Amsterdam”)                                   (reduce-fn                     {} A)                   ...
user> (letter-count “Amsterdam”)                                   (reduce-fn                     {} A)                   ...
user> (letter-count “Amsterdam”)                                   (reduce-fn                     {} A)                   ...
user> (letter-count “Amsterdam”)                                   (reduce-fn                     {} A)                   ...
sync     coord                                      clojure.core/ref                                      ([x] [x & option...
Macro advantage                                                                       let your code write itself          ...
(defn unless                                       “Executes body only if pred is false”                                  ...
(unless (odd? 11) (println “woot?”))                                     => “woot?”                                     (u...
(defmacro unless                                       [pred body]                                       (list if (list no...
(macroexpand (unless (odd? 12) (println "woot?")))                                                                       =...
(defmacro unless                                       [pred body]                                       `(if (not ~pred) ...
; automatic resource freeing                        (with-open [f (java.io.FileInputStream. "foo.txt")]                   ...
Lazy as a sloth                                                 when you ain’t gonna need it all                        A ...
List<Integer> allInts = new ArrayList<Integer>();                                 for (Integer i = 0; ; ++i) {            ...
(defn all-ints [from]                                 (cons from (lazy-seq (all-ints (inc from)))))                       ...
(with-open [session (hibernate-session)]                          (let [names [“carlo” “thomas” “luca” “nol”]             ...
user=> (doc doall)                        -------------------------                        clojure.core/doall             ...
Whatʼs next                        A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
* http://clojure.org                                            * ClojureScript                                           ...
April 18th                                                                       Amsterdam Clojurians                     ...
Q/A                        A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
http://imgs.xkcd.com/comics/lisp.jpg                        Thanks                                        @skuro          ...
Upcoming SlideShare
Loading in...5
×

A Dive Into Clojure

1,444

Published on

This presentation was given at the April Tech Meeting hosted by Orange11 (@orange11hq)

Published in: Technology, Education

Transcript of "A Dive Into Clojure"

  1. 1. A dive into Clojure Carlo Sciolla, Product Lead @ Backbase A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  2. 2. Carlo Sciolla Product Lead http://skuro.tk Amsterdam Clojurians @skuro http://www.backbase.com http://bit.ly/amsclj About me Next gen portal software for the Bank 2.0, a recent history of Alfresco and ECM specialist, Meetup organizer. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  3. 3. Motivational a.k.a. the towel they forgot to bring A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  4. 4. Ive seen things you people wouldnt believe Programming languages evolved throughout half a century. Paradigms rose and faded, with OOP and Java™ now the de-facto standards. Yet there’s more to programming than what objects have to offer. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  5. 5. * Single inheritance * [Almost] everything is an Object * Single dispatch * Non-covariant generics * Type erasures * C-like syntax * Frameworks composition The standard package There are a number of design choices behind the Java™ programming languages, and the ecosystem around it, that are quickly taken for granted. This effectively creates a horizon that can limit your sight. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  6. 6. A paradigm shift f (x) As much as they’ve disappeared from mainstream development, they’re now regaining momentum. Functional languages such as Scala and Clojure are getting the spots on. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  7. 7. macro let ? cons monad gensym trampoline recur zipper seq lambda The rocky road to LISP There are more than fifty years of history behind any modern Lisp, and while most of them have greatly influenced other languages, there’s a unique core bulk of concepts that only finds home in a Lisp. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  8. 8. “ Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a “” better programmer for the rest of your days Eric S. Raymond When you finally get it The very idea that you have to get Lisp is fascinating. As a matter of facts, every Lisp developer experienced a moment of illumination, after which all those parens finally fit together. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  9. 9. Open the parens to never look at programs the same way A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  10. 10. (defn hello [name] (println (str “Hello, ” name “!”))) Double rainbows As much as it might seem gibberish at first sight, at its very core there’s little to know about Lisp syntax. Clojure adds some syntactic sugar on top of standard Lisp, but the basics are all there. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  11. 11. (defn hello [name] (println (str “Hello, ” name “!”))) function calls Function calls The first symbol after an open parenthesis is interpreted as the name of the function to call, with all the other members passed as parameters. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  12. 12. user> (hello “World”) (defn hello [name] (println (str “Hello, ” name “!”))) Evaluation strategy A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  13. 13. user> (hello “World”) (defn hello [name] (println (str “Hello, ” name “!”))) Evaluation strategy Variables binding follow lexicographical order. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  14. 14. user> (hello “World”) (defn hello [name] (println (str “Hello, ” name “!”))) first invocation Evaluation strategy Variables binding follows lexicographical order. Then start from the innermost list. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  15. 15. user> (hello “World”) (defn hello [name] (println “Hello, World!”)) second invocation Evaluation strategy Variables binding follows lexicographical order. Then start from the innermost list. Substitute it with its yielded value, then repeat. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  16. 16. user> (hello “World”) Hello, World! (defn hello [name] nil) done Evaluation strategy Variables binding follows lexicographical order. Then start from the innermost list. Substitute it with its yielded value, then repeat. When we have a single value, we’re done and can yield a result. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  17. 17. user> (hello “World”) Hello, World! Read nil user> Eval Print Read, Eval, Print Loop You just saw the REPL in action. More than a simple function execution tool, it’s A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  18. 18. Whatʼs in a seq by any other interface it wouldn’t smell the same A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  19. 19. clojure.core/seq ([coll]) Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable. Much more than a collection A sequential access data structure, most of the Clojure standard library functions are able to process a sequence. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  20. 20. (seq (1 "test" :odd true)) => (1 "test" :odd true) (seq [1 "test" :odd true]) => (1 "test" :odd true) (seq {1 "test" :odd true}) => ([1 "test"] [:odd true]) (seq #{1 "test" :odd true}) => (1 :odd true "test") (seq “test”) => (t e s t) More than a collection A sequential access data structure, most of the Clojure standard library functions are able to process a sequence. Wrapping a collection in a sequence is just one function call away. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  21. 21. (map identity [1 2 3 4]) ; (1 2 3 4) (filter odd? ‘(1 2 3 4)) ; (1 3) (reduce str “test”) ; “test” Automatic conversion You don’t even have to bother converting your data structure, as the standard library will do that for you. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  22. 22. Immutability ‘cause Java beans give you gas A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  23. 23. Horse horse = new Horse(14); horse.getPosition(); ?? t On state and identity When using a POJO to model an identity, you fail to keep time into consideration. Mutable state makes it hard to reason about code execution in a concurrent environment. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  24. 24. (let [x {:one 1}] (assoc x :two 2) (println x) ; {:one 1} (println (assoc x :two 2))) ; {:one 1 :two 2} Persistent data structures In Clojure, data structures are immutable. There’s no “add to map”, you rather have to create a new map from the previous one, plus one element. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  25. 25. (defn letter-count [string] (let [reduce-fn (fn [counts letter] (let [count (or (counts letter) 0)] (assoc counts letter (inc count))))] (reduce reduce-fn {} string))) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  26. 26. user> (letter-count “Amsterdam”) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  27. 27. user> (letter-count “Amsterdam”) (reduce-fn {} A) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  28. 28. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  29. 29. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  30. 30. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) (reduce-fn {A 1 m 1 s 1} t) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  31. 31. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) (reduce-fn {A 1 m 1 s 1} t) (reduce-fn {A 1 m 1 s 1 t 1} e) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  32. 32. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) (reduce-fn {A 1 m 1 s 1} t) (reduce-fn {A 1 m 1 s 1 t 1} e) (reduce-fn {A 1 m 1 s 1 t 1 e 1} r) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  33. 33. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) (reduce-fn {A 1 m 1 s 1} t) (reduce-fn {A 1 m 1 s 1 t 1} e) (reduce-fn {A 1 m 1 s 1 t 1 e 1} r) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1} d) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  34. 34. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) (reduce-fn {A 1 m 1 s 1} t) (reduce-fn {A 1 m 1 s 1 t 1} e) (reduce-fn {A 1 m 1 s 1 t 1 e 1} r) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1} d) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1 d 1} a) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  35. 35. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) (reduce-fn {A 1 m 1 s 1} t) (reduce-fn {A 1 m 1 s 1 t 1} e) (reduce-fn {A 1 m 1 s 1 t 1 e 1} r) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1} d) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1 d 1} a) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1 d 1 a 1} m) Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  36. 36. user> (letter-count “Amsterdam”) (reduce-fn {} A) (reduce-fn {A 1} m) (reduce-fn {A 1 m 1} s) (reduce-fn {A 1 m 1 s 1} t) (reduce-fn {A 1 m 1 s 1 t 1} e) (reduce-fn {A 1 m 1 s 1 t 1 e 1} r) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1} d) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1 d 1} a) (reduce-fn {A 1 m 1 s 1 t 1 e 1 r 1 d 1 a 1} m) {A 1 m 2 s 1 t 1 e 1 r 1 d 1 a 1} Doing real work Immutability doesn’t get in the way of solving programming problems. If anything, it makes it easier to reason about execution! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  37. 37. sync coord clojure.core/ref ([x] [x & options]) clojure.core/atom ([x] [x & options]) clojure.core/agent ([state & options]) Software transactional memory When shared mutable state is really required, Clojure offers a number of constructs to handle it in a inherently thread safe manner, which frees you from resource locking. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  38. 38. Macro advantage let your code write itself A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  39. 39. (defn unless “Executes body only if pred is false” [pred body] (if (not pred) body) user code (unless (odd? 11) (println “woot?”)) (unless (odd? 12) (println “woot?”)) The classic example Can you tell what’s wrong with this code? A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  40. 40. (unless (odd? 11) (println “woot?”)) => “woot?” (unless (odd? 12) (println “woot?”)) => “woot?” Eager evaluation kills it When implementing unless as a function, its arguments are evaluated before unless itself is executed. This effectively prevents you from getting it right. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  41. 41. (defmacro unless [pred body] (list if (list not pred) body)) Macros FTW Macros look like functions, but are treated in a slightly different way: their arguments are passed unevaluated, and they’re supposed to return code! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  42. 42. (macroexpand (unless (odd? 12) (println "woot?"))) => (if (not (odd? 12)) (println "woot?")) Reflection on steroids You can inspect your macro with macroexpand and macroexpand-1. The result now looks good: treating code as data, we can shuffle all the pieces and put them in the order we want. This is LISP. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  43. 43. (defmacro unless [pred body] `(if (not ~pred) ~body)) Syntactic sugar The syntax quote reader macro helps you write macros, as you end up writing a “template” for the code you want to generate. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  44. 44. ; automatic resource freeing (with-open [f (java.io.FileInputStream. "foo.txt")] (loop [c (.read f)] (when (not (= -1 c)) (println (char c)) (recur (.read f))))) ; threading macro (-> c char println) Programmable programming language Macros are a powerful tool, and with great power comes great responsibility: use with care. That said, macros alone puts the whole concept of DSL just a built in of the language. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  45. 45. Lazy as a sloth when you ain’t gonna need it all A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  46. 46. List<Integer> allInts = new ArrayList<Integer>(); for (Integer i = 0; ; ++i) { allInts.add(i); } Infinite sequences In presence of strict (eager) evaluation, a collection of infinite elements will blow up your heap. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  47. 47. (defn all-ints [from] (cons from (lazy-seq (all-ints (inc from))))) (take 10 (all-ints 0)) => (0 1 2 3 4 5 6 7 8 9) Lazy sequences to the rescue A call to lazy-seq will put evaluation on hold, so that only the requested elements are “realized”. Also on the plus side, if you don’t hold a reference on the head the unused elements are garbage collected! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  48. 48. (with-open [session (hibernate-session)] (let [names [“carlo” “thomas” “luca” “nol”] results (map #(find-user % session) names)] (reset! users results)) (take 1 @users) ; org.hibernate.SessionException: Session was already closed The upsides and the flipside Most of the Clojure sequence library is made of lazy functions. While this is handy in most cases, you must be aware of what’s lazy in your code, as you might have to force the full realization of a seq. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  49. 49. user=> (doc doall) ------------------------- clojure.core/doall ([coll] [n coll]) When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time. The programmer in control You can choose whether is nice to have a lazy sequence, and when it’s best to have all the elements available at once. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  50. 50. Whatʼs next A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  51. 51. * http://clojure.org * ClojureScript * Overtone * core-logic * http://4clojure.com * #clojure on Freenode Some drops in the sea Despite being so young a language, the Clojure ecosystem is already huge. These are only a few ideas on where to start if you want to learn more about Clojure. A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  52. 52. April 18th Amsterdam Clojurians http://bit.ly/amsclj hosted by: Always open for business In two and a half year, we never missed a meetup. Come along and enjoy the Dutch Clojure community! A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  53. 53. Q/A A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  54. 54. http://imgs.xkcd.com/comics/lisp.jpg Thanks @skuro http://skuro.tk http://www.backbase.com A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×