SlideShare una empresa de Scribd logo
1 de 97
Macrobrew: Clojure macros
distilled
Abhinav Omprakash
@the_lazy_folder
Tech Talk
@the_lazy_folder
Macros look similar to functions
@the_lazy_folder
Arguments passed to the macro
are not evaluated
@the_lazy_folder
(defn func [x]
(println "inside the body")
x)
=>(func (println "hey!"))
hey!
inside the body
nil
@the_lazy_folder
(defmacro mac [x]
(println "inside the body")
x)
=>(mac (println "hey!"))
inside the body
hey!
nil
@the_lazy_folder
Data returned by the macro is
evaluated
@the_lazy_folder
(defn foo []
(list 1 2 3))
=>(foo)
(1 2 3)
=>(eval (foo))
; Execution error (ClassCastException); class
;java.lang.Long cannot be cast to class
clojure.lang.IFn
@the_lazy_folder
(defmacro foo []
(list 1 2 3))
=>(foo)
; Execution error (ClassCastException
; class java.lang.Long cannot be cast to class
clojure.lang.Ifn
@the_lazy_folder
=>(macroexpand '(foo))
(1 2 3)
@the_lazy_folder
Double Evaluation
@the_lazy_folder
What does a lisper do?
@the_lazy_folder
(func arg1 arg2)
‘(1 2 3)
@the_lazy_folder
user=> (count '(func arg1 arg2))
3
user=> (count '(1 2 3))
3
@the_lazy_folder
In lisp, we create lists.
@the_lazy_folder
@the_lazy_folder
The origin of the mighty macro
@the_lazy_folder
@the_lazy_folder
Symbols & Values
@the_lazy_folder
TABLE
@the_lazy_folder
@the_lazy_folder
@the_lazy_folder
犬
@the_lazy_folder
@the_lazy_folder
(def one 7)
user=> one
7
@the_lazy_folder
user=> 'one
one
user=> `one
user/one
@the_lazy_folder
(def one 7)
user=> (eval 'one)
7
@the_lazy_folder
Symbols can be assigned other
symbols
@the_lazy_folder
(def two ‘one)
user=> two
one
user=> (eval (two))
7
@the_lazy_folder
Are symbols values?
@the_lazy_folder
Pre-defined vs user-defined
symbols
@the_lazy_folder
420
[1 2 3]
"Not-a-string"
@the_lazy_folder
(defn add [& nums]
(apply + nums))
@the_lazy_folder
(defn add-2 [num1 num2]
(add num1 num2))
@the_lazy_folder
Revisiting double evaluation
@the_lazy_folder
symbols Value?
(write time)
Value?
(Compile
time)
Value?
(run time)
Predefined
symbols
NO Yes Yes
User defined
symbols
NO No yes
@the_lazy_folder
(defn add [& nums]
(apply + nums))
@the_lazy_folder
In functions,
we manipulate values.
@the_lazy_folder
In macros,
we manipulate symbols and values.
@the_lazy_folder
Let’s write a macro
(finally!)
@the_lazy_folder
1 + 2
@the_lazy_folder
(1 + 2)
@the_lazy_folder
[1 + 2]
@the_lazy_folder
‘(1 + 2)
@the_lazy_folder
(+ 1 2)
@the_lazy_folder
(1 + 2) => (+ 1 2)
@the_lazy_folder
(lt op rt) => (op lt rt)
@the_lazy_folder
(defmacro infix
[[lt op rt]]
`(~op ~lt ~rt))
@the_lazy_folder
=>(infix (1 + 2))
3
@the_lazy_folder
A 3-step process
@the_lazy_folder
1. Think about the data the macro will get.
(1 + 2)
@the_lazy_folder
2. Think about the data the macro will return.
(+ 1 2)
@the_lazy_folder
3. Think about how to transform that data.
(1 + 2) => (+ 1 2)
@the_lazy_folder
user=>(print-els [1 2 3])
1
2
3
[1 2 3]
@the_lazy_folder
(defmacro print-els [coll]
`(do ~(map println coll)
~coll))
@the_lazy_folder
(defmacro print-els [coll]
`(do ~(map println coll)
~coll))
user=>(print-els [1 2 3])
1
2
3
; Syntax error (IllegalArgumentException)
; Can't call nil, form: (nil nil nil)
@the_lazy_folder
(macroexpand-1 '(print-els [1 2 3]))
1
2
3
(do (nil nil nil) [1 2 3])
@the_lazy_folder
=>(do (map println [1 2 3]))
1
2
3
(nil nil nil)
=>(do nil nil nil [1 2 3])
[1 2 3]
@the_lazy_folder
=>(macroexpand-1 '(print-els [1 2 3]))
;expected
(do nil nil nil [1 2 3])
@the_lazy_folder
The unquote splice aka ~@ operator
(defmacro print-els [coll]
`(do ~@(map println coll)
~coll))
@the_lazy_folder
user=>(macroexpand-1 '(print-els [1 2 3]))
1
2
3
(do nil nil nil [1 2 3])
@the_lazy_folder
Symbol capture
@the_lazy_folder
(defmacro return-some-list [x]
(list 'let ['one 1]
['one x]))
user=>(return-some-list 5)
[1 5]
@the_lazy_folder
(def one "one")
user=>(return-some-list one)
[1 1]
@the_lazy_folder
user=>(macroexpand-1 '(return-some-list one))
(let [one 1] [one one])
@the_lazy_folder
The autogensym aka #
=>`one#
one__9411__auto__
@the_lazy_folder
(defmacro return-some-list [x]
`(let [one 1]
[one ~x]))
(defmacro return-some-list [x]
`(let [one# 1]
[one# ~x]))
@the_lazy_folder
(def one "one")
user=>(return-some-list one)
[1 "one"]
@the_lazy_folder
Common gotchas
@the_lazy_folder
1. Not resolving arguments to a
value inside the macro
@the_lazy_folder
(defmacro infix [[lt op rt]]
‘(op lt rt))
=>(macroexpand-1 '(infix (1 + 2)))
(op lt rt)
@the_lazy_folder
2. The macro is NOT the first
element in the list
@the_lazy_folder
(map infix [(1 + 2) (3 + 4)])
@the_lazy_folder
3. Passing a symbol instead of a
value
@the_lazy_folder
(defmacro mul-2 [xs]
`(* 2 ~@xs))
=>(mul-2 [1 2])
4
@the_lazy_folder
(defmacro mul-2 [xs]
`(* 2 ~@xs))
(defn multiply-by-2 [nums]
(mul-2 nums))
; Syntax error
; Don't know how to create ISeq from:
clojure.lang.Symbol
@the_lazy_folder
Practical Advice
@the_lazy_folder
Always use a syntax quote
@the_lazy_folder
“Don’t write a macro”
-Not me
@the_lazy_folder
Actions have consequences
@the_lazy_folder
Macros are infectious
@the_lazy_folder
(defmacro add [& args]
`(+ ~@args))
user=>(add 1 2 3)
6
@the_lazy_folder
=>(map #(apply + %) [[1 2 3] [2 4]])
(6 6)
@the_lazy_folder
(defmacro add-vecs [vecs]
(loop [f (first vecs)
r (rest vecs)
res `(list)]
(if (seq r)
(recur (first r) (rest r) (concat
res `((add ~@f))))
(concat res `((add ~@f))))))
user=> (add-vecs [[1 2] [3 4]])
(3 7) @the_lazy_folder
Macros are not reusable
@the_lazy_folder
Macros are not composable
@the_lazy_folder
Composition is king.
(even the OO folks know that)
@the_lazy_folder
When should you write a macro?
@the_lazy_folder
When a function just won’t do
@the_lazy_folder
When you need to prevent
evaluation of arguments
@the_lazy_folder
Incanter’s infix notation
User=> ($= 7 + 8 - 2)
13
@the_lazy_folder
When you want to extend
another macro
@the_lazy_folder
Syntactic sugar
@the_lazy_folder
Speed
(no, not that kind)
@the_lazy_folder
I promised a wedding photo
@the_lazy_folder
@the_lazy_folder
Thank you
@the_lazy_folder

Más contenido relacionado

La actualidad más candente

KOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
KOLEJ KOMUNITI - Sijil Aplikasi Perisian KomputerKOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
KOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
Aiman Hud
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
timourian
 

La actualidad más candente (20)

Introduction to julia
Introduction to juliaIntroduction to julia
Introduction to julia
 
Python Modules and Libraries
Python Modules and LibrariesPython Modules and Libraries
Python Modules and Libraries
 
Evolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveEvolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and Effective
 
Ruby Refinements: the Worst Feature You Ever Loved
Ruby Refinements: the Worst Feature You Ever LovedRuby Refinements: the Worst Feature You Ever Loved
Ruby Refinements: the Worst Feature You Ever Loved
 
java 8 Hands on Workshop
java 8 Hands on Workshopjava 8 Hands on Workshop
java 8 Hands on Workshop
 
Python dictionary : past, present, future
Python dictionary: past, present, futurePython dictionary: past, present, future
Python dictionary : past, present, future
 
The Language for future-julia
The Language for future-juliaThe Language for future-julia
The Language for future-julia
 
Haskell
HaskellHaskell
Haskell
 
Porting to Python 3
Porting to Python 3Porting to Python 3
Porting to Python 3
 
Python-Tuples
Python-TuplesPython-Tuples
Python-Tuples
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of Abstraction
 
Apache Pig Relational Operators - II
Apache Pig Relational Operators - II Apache Pig Relational Operators - II
Apache Pig Relational Operators - II
 
KOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
KOLEJ KOMUNITI - Sijil Aplikasi Perisian KomputerKOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
KOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
 
Merging tables using R
Merging tables using R Merging tables using R
Merging tables using R
 
C# features through examples
C# features through examplesC# features through examples
C# features through examples
 
Lesson11
Lesson11Lesson11
Lesson11
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
 
Python course Day 1
Python course Day 1Python course Day 1
Python course Day 1
 
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCEFUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
FUNCTIONS IN PYTHON, CLASS 12 COMPUTER SCIENCE
 
Introduction to Python - Training for Kids
Introduction to Python - Training for KidsIntroduction to Python - Training for Kids
Introduction to Python - Training for Kids
 

Similar a Macrobrew: Clojure macros distilled

Predictably
PredictablyPredictably
Predictably
ztellman
 
“Tasks” in NetLogo 5.0beta1
“Tasks” in NetLogo 5.0beta1“Tasks” in NetLogo 5.0beta1
“Tasks” in NetLogo 5.0beta1
SethTisue
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
Graham Dumpleton
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
New Relic
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
Introduction aux Macros
Introduction aux MacrosIntroduction aux Macros
Introduction aux Macros
univalence
 
Intro to Functional Programming Workshop (code4lib)
Intro to Functional Programming Workshop (code4lib)Intro to Functional Programming Workshop (code4lib)
Intro to Functional Programming Workshop (code4lib)
Will Kurt
 

Similar a Macrobrew: Clojure macros distilled (20)

Full Stack Clojure
Full Stack ClojureFull Stack Clojure
Full Stack Clojure
 
Predictably
PredictablyPredictably
Predictably
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Intro
 
Writing Macros
Writing MacrosWriting Macros
Writing Macros
 
PythonOOP
PythonOOPPythonOOP
PythonOOP
 
Learning Lisp
Learning LispLearning Lisp
Learning Lisp
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Functional Programming inside OOP? It’s possible with Python
Functional Programming inside OOP? It’s possible with PythonFunctional Programming inside OOP? It’s possible with Python
Functional Programming inside OOP? It’s possible with Python
 
“Tasks” in NetLogo 5.0beta1
“Tasks” in NetLogo 5.0beta1“Tasks” in NetLogo 5.0beta1
“Tasks” in NetLogo 5.0beta1
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
TDC2016SP - Trilha Programação Funcional
TDC2016SP - Trilha Programação FuncionalTDC2016SP - Trilha Programação Funcional
TDC2016SP - Trilha Programação Funcional
 
Haskell 101
Haskell 101Haskell 101
Haskell 101
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Introduction aux Macros
Introduction aux MacrosIntroduction aux Macros
Introduction aux Macros
 
(first '(Clojure.))
(first '(Clojure.))(first '(Clojure.))
(first '(Clojure.))
 
Intro to Functional Programming Workshop (code4lib)
Intro to Functional Programming Workshop (code4lib)Intro to Functional Programming Workshop (code4lib)
Intro to Functional Programming Workshop (code4lib)
 

Último

CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
anilsa9823
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
anilsa9823
 

Último (20)

Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

Macrobrew: Clojure macros distilled

Notas del editor

  1. macros return lists most of the time
  2. macros return lists most of the time
  3. We build lists. Lisp programs are structured data
  4. You’re creating a new programmer, faster and cheaper and easier than having kids and trying to get them to learn programming but arguable less fun. Find a different framing
  5. There is one photo of the wedding and I’ll show you at the end
  6. Lambda with arms Banana peel A person doing a split Symbols are hard to talk about. Lisp has a way For the smart people that I thought it means table
  7. WE are so used to this, We mentally substitute the symbol for its value
  8. Since symbols can be assigned to other symbols
  9. Why is there a need for double evaluation?
  10. asdfasdfasdf
  11. Explain how
  12. Marco needs to write the function
  13. Remember I mentioned marco was not happy about john misspelling his name?
  14. Let has a lexical scope One shadows the one
  15. Note the syntax quote Lets rewrite the macro with a syntax quote