![Page 1: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/1.jpg)
Bending Clojure to your Will: Macros and Domain Specific
LanguagesLambdaJam - Brisbane, 2013
Leonardo Borges@leonardo_borgeswww.leonardoborges.comwww.thoughtworks.com
Thursday, 16 May 13
![Page 2: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/2.jpg)
Leonardo Borges@leonardo_borgeswww.leonardoborges.comwww.thoughtworks.com
• Thoughtworker• Functional Programming enthusiast• Clojure Evangelist• Founder & Organiser of the Sydney Clojure User Group (clj-syd)• World traveller• Fan of Murray’s Beers :)
about:me
Thursday, 16 May 13
![Page 3: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/3.jpg)
Why macros?
Thursday, 16 May 13
![Page 4: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/4.jpg)
It’s fun
Thursday, 16 May 13
![Page 5: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/5.jpg)
Thursday, 16 May 13
![Page 6: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/6.jpg)
It’s powerful
Thursday, 16 May 13
![Page 7: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/7.jpg)
Thursday, 16 May 13
![Page 8: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/8.jpg)
It’s mind bending
Thursday, 16 May 13
![Page 9: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/9.jpg)
Thursday, 16 May 13
![Page 10: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/10.jpg)
If you give someone Fortran, he has Fortran.If you give someone Lisp, he has any language he pleases.
- Guy Steele
Thursday, 16 May 13
![Page 11: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/11.jpg)
But what are macros?
Thursday, 16 May 13
![Page 12: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/12.jpg)
•Data is code is data•Programs that write programs•Magic happens at macro-expansion time•Most control structures in Clojure are built out of macros
But what are macros?
Thursday, 16 May 13
![Page 13: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/13.jpg)
Macro-expansion time
(defmacro arg-logger [& args] (prn "Called with: " args) `(do ~@args))
Thursday, 16 May 13
![Page 14: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/14.jpg)
Macro-expansion time
(arg-logger (+ 2 3))
Every usage of a macro
(do (+ 2 3))
Gets replaced with its expansion
prior to compilationThursday, 16 May 13
![Page 15: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/15.jpg)
Runtime
(arg-logger (+ 2 3))
;;"Called with: " ((+ 2 3))
Arguments are handed into macros unevaluated
Thursday, 16 May 13
![Page 16: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/16.jpg)
More on that later
Thursday, 16 May 13
![Page 17: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/17.jpg)
Debugging macros
(macroexpand '(cond true "true" :else "false"))
;;(if true "true" (clojure.core/cond :else "false"))
Thursday, 16 May 13
![Page 18: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/18.jpg)
Debugging macros(require '[clojure.walk :as w])
(w/macroexpand-all '(cond true "true" :else "false"))
;;(if true "true" (if :else "false" nil))
Thursday, 16 May 13
![Page 19: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/19.jpg)
Quoting Prevents evaluation
(def my-list (1 2 3)) ;java.lang.Integer cannot be cast to clojure.lang.IFn
(def my-list '(1 2 3)) ;Success!
'my-list ;my-list'(1 2 3) ;(1 2 3)
Thursday, 16 May 13
![Page 20: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/20.jpg)
Syntax-quote
Automatically qualifies all unqualified symbols
`my-list ; user/my-list`prn ; clojure.core/prn
Note the backtick!
Thursday, 16 May 13
![Page 21: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/21.jpg)
Unquote
Evaluates some forms in a quoted expression
Before unquoting...`(map even? my-list);;(clojure.core/map clojure.core/even? user/my-list)
After...`(map even? '~my-list);;(clojure.core/map clojure.core/even? (quote (1 2 3)))
Thursday, 16 May 13
![Page 22: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/22.jpg)
Unquote-splicing
“Unpacks” a sequence
Before unquote-splicing...
`(+ ~my-list) ;;(clojure.core/+ (1 2 3))
(eval `(+ ~my-list)) ;;java.lang.Integer cannot be cast to clojure.lang.IFn
Thursday, 16 May 13
![Page 23: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/23.jpg)
Unquote-splicing
After...
`(+ ~@my-list) ;;(clojure.core/+ 1 2 3)
(eval `(+ ~@my-list)) ;;6
Thursday, 16 May 13
![Page 24: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/24.jpg)
All of these are useful inside macros!
Thursday, 16 May 13
![Page 25: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/25.jpg)
Jam time!
Thursday, 16 May 13
![Page 26: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/26.jpg)
Jam time!
•Get the code - http://bit.ly/ylj13-macros•Make sure you have leiningen 2.x installed•Run $lein midje or lein midje :autotest from the project root•Watch the tests fail!•Fix them :)
Thursday, 16 May 13
![Page 27: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/27.jpg)
Summary(defmacro macro-name [& args] ...)Defining macros
(def my-list '(1 2 3))Quoting
`my-list ; user/my-listSyntax-quote
`(+ ~my-list) ;;(clojure.core/+ (1 2 3))Unquote-splicing
(macroexpand '...)
(require '[clojure.walk :as w])(w/macroexpand-all '...)
Debugging
Thursday, 16 May 13
![Page 28: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/28.jpg)
Questions?Leonardo Borges
@leonardo_borgeswww.leonardoborges.comwww.thoughtworks.com
Thursday, 16 May 13
![Page 29: Bending Clojure to your Will: Macros and Domain Specific ... › yowlambdajam2013 › ... · Leonardo Borges @leonardo_borges • Thoughtworker • Functional Programming enthusiast](https://reader034.vdocument.in/reader034/viewer/2022042407/5f2146bfd5e30221ac69e3a8/html5/thumbnails/29.jpg)
Go deeper
Let Over Lambda - http://bit.ly/let-over-lambda
On Lisp - http://bit.ly/on-lisp-book
Thursday, 16 May 13