SlideShare a Scribd company logo
1 of 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

More Related Content

What's hot

Introduction to julia
Introduction to juliaIntroduction to julia
Introduction to julia岳華 杜
 
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 EffectiveNaresha K
 
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 Lovedpaoloperrotta
 
java 8 Hands on Workshop
java 8 Hands on Workshopjava 8 Hands on Workshop
java 8 Hands on WorkshopJeanne Boyarsky
 
Python dictionary : past, present, future
Python dictionary: past, present, futurePython dictionary: past, present, future
Python dictionary : past, present, futuredelimitry
 
The Language for future-julia
The Language for future-juliaThe Language for future-julia
The Language for future-julia岳華 杜
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of AbstractionAlex Miller
 
Apache Pig Relational Operators - II
Apache Pig Relational Operators - II Apache Pig Relational Operators - II
Apache Pig Relational Operators - II Rupak Roy
 
KOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
KOLEJ KOMUNITI - Sijil Aplikasi Perisian KomputerKOLEJ KOMUNITI - Sijil Aplikasi Perisian Komputer
KOLEJ KOMUNITI - Sijil Aplikasi Perisian KomputerAiman Hud
 
Merging tables using R
Merging tables using R Merging tables using R
Merging tables using R Rupak Roy
 
C# features through examples
C# features through examplesC# features through examples
C# features through examplesZayen Chagra
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.jstimourian
 
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 SCIENCEVenugopalavarma Raja
 
Introduction to Python - Training for Kids
Introduction to Python - Training for KidsIntroduction to Python - Training for Kids
Introduction to Python - Training for KidsAimee Maree Forsstrom
 

What's hot (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 to Macrobrew: Clojure macros distilled

Predictably
PredictablyPredictably
Predictablyztellman
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Introthnetos
 
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 2015Michiel Borkent
 
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 PythonCarlos V.
 
“Tasks” in NetLogo 5.0beta1
“Tasks” in NetLogo 5.0beta1“Tasks” in NetLogo 5.0beta1
“Tasks” in NetLogo 5.0beta1SethTisue
 
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 RelicGraham Dumpleton
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicNew Relic
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
TDC2016SP - Trilha Programação Funcional
TDC2016SP - Trilha Programação FuncionalTDC2016SP - Trilha Programação Funcional
TDC2016SP - Trilha Programação Funcionaltdc-globalcode
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMsunng87
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)Jacek Laskowski
 
Introduction aux Macros
Introduction aux MacrosIntroduction aux Macros
Introduction aux Macrosunivalence
 
(first '(Clojure.))
(first '(Clojure.))(first '(Clojure.))
(first '(Clojure.))niklal
 
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 to 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)
 

Recently uploaded

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 PrecisionSolGuruz
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
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.pdfkalichargn70th171
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
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 ...OnePlan Solutions
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
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 ...harshavardhanraghave
 
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...ICS
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
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.docxComplianceQuest1
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
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...MyIntelliSource, Inc.
 
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.pdfWave PLM
 

Recently uploaded (20)

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
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
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
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
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 ...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
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 ...
 
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...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
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
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
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...
 
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
 

Macrobrew: Clojure macros distilled

Editor's Notes

  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