A Dive Into Clojure
Upcoming SlideShare
Loading in...5
×
 

A Dive Into Clojure

on

  • 1,676 views

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

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

Statistics

Views

Total Views
1,676
Views on SlideShare
1,674
Embed Views
2

Actions

Likes
4
Downloads
41
Comments
0

2 Embeds 2

https://si0.twimg.com 1
http://paper.li 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    A Dive Into Clojure A Dive Into Clojure Presentation Transcript

    • A dive into Clojure Carlo Sciolla, Product Lead @ Backbase A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • 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
    • Motivational a.k.a. the towel they forgot to bring A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • 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
    • * 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
    • 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
    • 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
    • “ 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
    • Open the parens to never look at programs the same way A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • (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
    • (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
    • user> (hello “World”) (defn hello [name] (println (str “Hello, ” name “!”))) Evaluation strategy A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • (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
    • (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
    • Immutability ‘cause Java beans give you gas A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • 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
    • (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
    • (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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • Macro advantage let your code write itself A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • (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
    • (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
    • (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
    • (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
    • (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
    • ; 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
    • Lazy as a sloth when you ain’t gonna need it all A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • 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
    • (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
    • (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
    • 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
    • Whatʼs next A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • * 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
    • 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
    • Q/A A DIVE INTO CLOJURE | April 6, 2012 | @skuroFriday, April 6, 2012
    • 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