SlideShare a Scribd company logo
1 of 28
Download to read offline
Writing Macros
Chapter 8 of CLOJURE for the BRAVE and TRUE
( LINK : http://www.braveclojure.com/writing-macros/ )
2016/8/11 - ClojureTW 讀書會 @ 摩茲工寮, 台北
Macros Are Essential
● Macros are an integral part of Clojure development
— they’re even used to provide fundamental operations.
● EXAMPLE: “ when ” = “ if ” + “ do ”
( macroexpand ‘( when boolean-expression
expression-1
expression-2
expression-3))
; => (if boolean-expression
; (do expression-1
; expression-2
; expression-3))
Anatomy of a Macro
Macros receive unevaluated, arbitrary data structures as arguments and
return data structures that Clojure evaluates
defmacro defn
(evaluated)
Building Lists for Evaluation
● Macro writing is all about building a list for Clojure to evaluate
defmacro final list to evaluate
unevaluated arguments
Building Lists for Evaluation
● Macro writing is all about building a list for Clojure to evaluate
(defmacro infix-2
[[operand1 op operand2]]
(list op operand1 operand2))
Building Lists for Evaluation
● You’ll need to be extra careful about the difference
between a symbol and its value
Macro
(building lists)
closed-box
(list of symbol)
Evaluation
Building Lists for Evaluation
● You’ll need to be extra careful about the difference
between a symbol and its value
(defmacro my-print-whoopsie
[expression]
(list let [result expression]
(list println result)
result))
EXCEPTION
Building Lists for Evaluation
● You’ll need to be extra careful about the difference
between a symbol and its value
(defmacro my-print-whoopsie
[expression]
(list 'let ['result expression]
(list 'println 'result)
result))
OK!
Building Lists for Evaluation
Single Quoting vs. Syntax Quoting
'+
; => +
`+
; => clojure.core/+
Syntax quoting will always include the symbol’s full namespace
→ Help you avoid name collisions
Building Lists for Evaluation
Single Quoting vs. Syntax Quoting
'(+ 1 ~(inc 1))
; => (+ 1 ~(inc 1))
`(+ 1 ~(inc 1))
; => (clojure.core/+ 1 2)
full namespace evaluated instead of being quoted!
Building Lists for Evaluation
Single Quoting vs. Syntax Quoting
The other difference between quoting and syntax quoting is that the latter
allows you to unquote forms using the tilde, ~
( q u o t e d )
‘
( q u o t e d
` ~ ( evaluated ) q u o t e d )
Using Syntax Quoting in a Macro
If you want your macro to return multiple forms for Clojure to evaluate,
make sure to wrap them in a do.
(defmacro code-critic
"Phrases are courtesy Hermes Conrad from Futurama"
[bad good]
`(do (println "Great squid of Madrid, this is bad code:"
(quote ~bad))
(println "Sweet gorilla of Manila, this is good code:"
(quote ~good))))
Refactoring a Macro and Unquote Splicing
(do
((clojure.core/println "criticism" '(1 + 1))
(clojure.core/println "criticism" '(+ 1 1))))
(do
(nil nil))
EXCEPTION
NullPointerException
nil function nil argument
Unquote splicing was invented precisely to handle this kind of situation
Refactoring a Macro and Unquote Splicing
`(+ ~(list 1 2 3))
; => (clojure.core/+ (1 2 3))
`(+ ~@(list 1 2 3))
; => (clojure.core/+ 1 2 3) Great !
(defmacro code-critic
[{:keys [good bad]}]
`(do ~@(map #(apply criticize-code %)
[["Sweet lion of Zion, this is bad code:" bad]
["Great cow of Moscow, this is good code:"
good]])))
do & map
so convenient !
Refactoring a Macro and Unquote Splicing
( q u o t e d
` ~ ( evaluated ) q u o t e d )
( q u o t e d )
‘
( q u o t e d
` ~ ( evaluated ) q u o t e d )@
Unquote
simple function
simple function
+ do, map … etc.
Things to Watch Out For
1. Variable Capture
(def message "Good job!")
(defmacro with-mischief
[& stuff-to-do]
(concat (list 'let ['message "Oh, big deal!"])
stuff-to-do))
(with-mischief
(println "Here's how I feel about that thing you did: " message))
; => Here's how I feel about that thing you did:Oh, big deal!
Things to Watch Out For
1. Variable Capture
Uncorrelated Macro
letB -> C
function
( input: A)
( output: A)
function
( input: A)
( B ->C)
( output: A)
function
( input: B)
( B ->C)
( output: C)
B
B
B
C
Things to Watch Out For
1. Variable Capture
(def message "Good job!")
(defmacro with-mischief
[& stuff-to-do]
`(let [message "Oh, big deal!" ]
~@stuff-to-do))
(with-mischief
(println "Here's how I feel about that thing you did: " message))
; Exception: Can't let qualified name: user/message
Syntax quoting is designed to prevent you from accidentally capturing
variables within macros.
Things to Watch Out For
1. Variable Capture
(defmacro without-mischief
[& stuff-to-do]
(let [macro-message (gensym 'message)]
`(let [~macro-message "Oh, big deal!" ]
~@stuff-to-do
(println "I still need to say: " ~macro-message))))
(without-mischief
(println "Here's how I feel about that thing you did: " message))
; => Here's how I feel about that thing you did: Good job!
(gensym 'message)
; => message4763
Symbol prefix !
This example avoids variable capture by using gensym to create a new, unique
symbol that then gets bound to macro-variable.
Things to Watch Out For
1. Variable Capture
Uncorrelated Macro
gensym let B -> C
function
( input: A)
( output: A)
function
( input: A)
( gensym B ->C)
( output: A)
function
( input: B)
( B123 ->C)
( output: B)
B
B
B
B
Things to Watch Out For
1. Variable Capture
`(blarg# blarg#)
(blarg__2869__auto__ blarg__2869__auto__)
`(let [name# "Larry Potter" ] name#)
; => (clojure.core/let [name__2872__auto__ "Larry Potter"]
name__2872__auto__)
Because this is such a common pattern, you can use an auto-gensym.
Auto-gensyms are more concise and convenient ways to use gensyms
Things to Watch Out For
( q u o t e d
` ~ ( evaluated ) q u o t e d )
( q u o t e d
` ~ ( evaluated ) q u o t e d )@
Unquote
+ do, map … etc.
( quoted
` ~ ( evaluated )( let [ var # … ]
autogem
Things to Watch Out For
2. Double Evaluation
(defmacro report
[to-try]
`(if ~to-try
(println (quote ~to-try) "was successful:" ~to-try)
(println (quote ~to-try) "was not successful:" ~to-try)))
1
2
3
Things to Watch Out For
2. Double Evaluation
Repeated actions in Macro
let repeat 100 times
function
( input: A)
a lot of calc
( output: A)
function
( input: A)
a lot of
repeating calc
( output: A)
B
B
B
function
( input: A)
a lot of
repeating calc
( output: A)
Waiting for
calculation process ….
Things to Watch Out For
2. Double Evaluation
(defmacro report
[to-try]
`(if ~to-try
(println (quote ~to-try) "was successful:" ~to-try)
(println (quote ~to-try) "was not successful:" ~to-try)))
1
2
3
(defmacro report
[to-try]
`(let [result# ~to-try]
(if result#
(println (quote ~to-try) "was successful:" result#)
(println (quote ~to-try) "was not successful:" result#))))
1 Double eval ? → let
→ Var capture ? → auto-gensym
Things to Watch Out For
3. Macros All the Way Down
(doseq [code ['(= 1 1) '(= 1 2)]]
(report code))
; => code was successful: (= 1 1)
; => code was successful: (= 1 2)
(defmacro doseq-macro
[macroname & args]
`(do
~@(map (fn [arg] (list macroname arg)) args)))
(doseq-macro report (= 1 1) (= 1 2))
; => (= 1 1) was successful: true
; => (= 1 2) was not successful: false
report operating at macro expansion
time, just can’t access those values.
To resolve this situation,
you might write another macro
Things to Watch Out For
3. Macros All the Way Down
● It’s easy to paint yourself into a corner, making it impossible to
accomplish anything with run-of-the-mill function calls.
● They only really compose with each other, so by using them, you might be
missing out on the other kinds of composition (functional,
object-oriented) available to you in Clojure.
Macro Macro
Macro
Macro
Macro
Macro
Macro
Macro
Macro
Macro
Macro
Macro
Summary
Don’t listen to these prudes
— at least, not at first! Go out there and have a good time.
That’s the only way you’ll learn the situations where it’s appropriate
to use macros. You’ll come out the other side knowing how to use
macros with skill and panache.

More Related Content

What's hot

서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015NAVER / MusicPlatform
 
JavaScript Control Statements I
JavaScript Control Statements IJavaScript Control Statements I
JavaScript Control Statements IReem Alattas
 
The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196Mahmoud Samir Fayed
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overviewgourav kottawar
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181Mahmoud Samir Fayed
 
JavaScript Control Statements II
JavaScript Control Statements IIJavaScript Control Statements II
JavaScript Control Statements IIReem Alattas
 
Iterative control structures, looping, types of loops, loop working
Iterative control structures, looping, types of loops, loop workingIterative control structures, looping, types of loops, loop working
Iterative control structures, looping, types of loops, loop workingNeeru Mittal
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
What's New In C# 5.0 - Rumos InsideOut
What's New In C# 5.0 - Rumos InsideOutWhat's New In C# 5.0 - Rumos InsideOut
What's New In C# 5.0 - Rumos InsideOutPaulo Morgado
 
The Ring programming language version 1.10 book - Part 101 of 212
The Ring programming language version 1.10 book - Part 101 of 212The Ring programming language version 1.10 book - Part 101 of 212
The Ring programming language version 1.10 book - Part 101 of 212Mahmoud Samir Fayed
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerAndrey Karpov
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2zindadili
 
Concurrency in Programming Languages
Concurrency in Programming LanguagesConcurrency in Programming Languages
Concurrency in Programming LanguagesYudong Li
 
Check the output of the following code then recode it to eliminate fu
 Check the output of the following code then recode it to eliminate fu Check the output of the following code then recode it to eliminate fu
Check the output of the following code then recode it to eliminate fulicservernoida
 
The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210Mahmoud Samir Fayed
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScriptGarth Gilmour
 
The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180Mahmoud Samir Fayed
 

What's hot (20)

서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
JavaScript Control Statements I
JavaScript Control Statements IJavaScript Control Statements I
JavaScript Control Statements I
 
C# 6.0 Preview
C# 6.0 PreviewC# 6.0 Preview
C# 6.0 Preview
 
The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196
 
classes & objects in cpp overview
classes & objects in cpp overviewclasses & objects in cpp overview
classes & objects in cpp overview
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181
 
JavaScript Control Statements II
JavaScript Control Statements IIJavaScript Control Statements II
JavaScript Control Statements II
 
Iterative control structures, looping, types of loops, loop working
Iterative control structures, looping, types of loops, loop workingIterative control structures, looping, types of loops, loop working
Iterative control structures, looping, types of loops, loop working
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
What's New In C# 5.0 - Rumos InsideOut
What's New In C# 5.0 - Rumos InsideOutWhat's New In C# 5.0 - Rumos InsideOut
What's New In C# 5.0 - Rumos InsideOut
 
The Ring programming language version 1.10 book - Part 101 of 212
The Ring programming language version 1.10 book - Part 101 of 212The Ring programming language version 1.10 book - Part 101 of 212
The Ring programming language version 1.10 book - Part 101 of 212
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
 
Operator overloading2
Operator overloading2Operator overloading2
Operator overloading2
 
Concurrency in Programming Languages
Concurrency in Programming LanguagesConcurrency in Programming Languages
Concurrency in Programming Languages
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
Clang tidy
Clang tidyClang tidy
Clang tidy
 
Check the output of the following code then recode it to eliminate fu
 Check the output of the following code then recode it to eliminate fu Check the output of the following code then recode it to eliminate fu
Check the output of the following code then recode it to eliminate fu
 
The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180
 

Viewers also liked

不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsしてmitsutaka mimura
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Leonardo Borges
 
A little exercise with clojure macro
A little exercise with clojure macroA little exercise with clojure macro
A little exercise with clojure macroZehua Liu
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMsunng87
 
入門ClojureScript
入門ClojureScript入門ClojureScript
入門ClojureScriptsohta
 
Macros in Clojure
Macros in ClojureMacros in Clojure
Macros in Clojuresohta
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Leonardo Borges
 
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...AboutYouGmbH
 
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものClojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものsohta
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)Jacek Laskowski
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojureAbbas Raza
 
プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例sohta
 
Clojure from ground up
Clojure from ground upClojure from ground up
Clojure from ground upDi Xu
 

Viewers also liked (19)

不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
 
Patterns
PatternsPatterns
Patterns
 
A Dive Into Clojure
A Dive Into ClojureA Dive Into Clojure
A Dive Into Clojure
 
A little exercise with clojure macro
A little exercise with clojure macroA little exercise with clojure macro
A little exercise with clojure macro
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
 
入門ClojureScript
入門ClojureScript入門ClojureScript
入門ClojureScript
 
Macros in Clojure
Macros in ClojureMacros in Clojure
Macros in Clojure
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
 
Clojure的魅力
Clojure的魅力Clojure的魅力
Clojure的魅力
 
Clojure概览
Clojure概览Clojure概览
Clojure概览
 
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
 
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものClojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
Clojure: a LISP for the JVM
Clojure: a LISP for the JVMClojure: a LISP for the JVM
Clojure: a LISP for the JVM
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
DSL in Clojure
DSL in ClojureDSL in Clojure
DSL in Clojure
 
プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例プログラミング言語Clojureのニャンパスでの活用事例
プログラミング言語Clojureのニャンパスでの活用事例
 
Clojure from ground up
Clojure from ground upClojure from ground up
Clojure from ground up
 

Similar to Writing Macros

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 Concepts for OOP Developers
Functional Concepts for OOP DevelopersFunctional Concepts for OOP Developers
Functional Concepts for OOP Developersbrweber2
 
Learn a language : LISP
Learn a language : LISPLearn a language : LISP
Learn a language : LISPDevnology
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Phil Calçado
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoRodolfo Carvalho
 
關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......hugo lu
 
Clean Code JavaScript
Clean Code JavaScriptClean Code JavaScript
Clean Code JavaScriptRiza Fahmi
 
Introduction aux Macros
Introduction aux MacrosIntroduction aux Macros
Introduction aux Macrosunivalence
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScriptChengHui Weng
 
Introduction to julia
Introduction to juliaIntroduction to julia
Introduction to julia岳華 杜
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial javaTpoint s
 
ClojureScript: The Good Parts
ClojureScript: The Good PartsClojureScript: The Good Parts
ClojureScript: The Good PartsKent Ohashi
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Introthnetos
 

Similar to Writing Macros (20)

Meta Object Protocols
Meta Object ProtocolsMeta Object Protocols
Meta Object Protocols
 
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
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Functional Concepts for OOP Developers
Functional Concepts for OOP DevelopersFunctional Concepts for OOP Developers
Functional Concepts for OOP Developers
 
Learn a language : LISP
Learn a language : LISPLearn a language : LISP
Learn a language : LISP
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Go 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX GoGo 1.10 Release Party - PDX Go
Go 1.10 Release Party - PDX Go
 
關於測試,我說的其實是......
關於測試,我說的其實是......關於測試,我說的其實是......
關於測試,我說的其實是......
 
Clean Code JavaScript
Clean Code JavaScriptClean Code JavaScript
Clean Code JavaScript
 
Introduction aux Macros
Introduction aux MacrosIntroduction aux Macros
Introduction aux Macros
 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
 
Introduction to julia
Introduction to juliaIntroduction to julia
Introduction to julia
 
Clojure intro
Clojure introClojure intro
Clojure intro
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial
 
Cpp tutorial
Cpp tutorialCpp tutorial
Cpp tutorial
 
ClojureScript: The Good Parts
ClojureScript: The Good PartsClojureScript: The Good Parts
ClojureScript: The Good Parts
 
Golang dot-testing-lite
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-lite
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Intro
 

More from RueiCi Wang

李群在機器學習中的應用(超基礎篇)
李群在機器學習中的應用(超基礎篇)李群在機器學習中的應用(超基礎篇)
李群在機器學習中的應用(超基礎篇)RueiCi Wang
 
金融市場資料的區間分析法
金融市場資料的區間分析法金融市場資料的區間分析法
金融市場資料的區間分析法RueiCi Wang
 
如何打造社會企業:重點文摘
如何打造社會企業:重點文摘如何打造社會企業:重點文摘
如何打造社會企業:重點文摘RueiCi Wang
 
[US學習資料] 如何編列組織的預算?
[US學習資料] 如何編列組織的預算?[US學習資料] 如何編列組織的預算?
[US學習資料] 如何編列組織的預算?RueiCi Wang
 
如何推動新板Ur school網站前進
如何推動新板Ur school網站前進如何推動新板Ur school網站前進
如何推動新板Ur school網站前進RueiCi Wang
 
UrSchool 三分鐘搞懂願景
UrSchool 三分鐘搞懂願景UrSchool 三分鐘搞懂願景
UrSchool 三分鐘搞懂願景RueiCi Wang
 
台師大合作提案
台師大合作提案台師大合作提案
台師大合作提案RueiCi Wang
 
Urschoolbookv031
Urschoolbookv031Urschoolbookv031
Urschoolbookv031RueiCi Wang
 
成大校園團隊招募計畫
成大校園團隊招募計畫成大校園團隊招募計畫
成大校園團隊招募計畫RueiCi Wang
 
升學諮詢概念分享會
升學諮詢概念分享會升學諮詢概念分享會
升學諮詢概念分享會RueiCi Wang
 
WikiUrSchool建置計畫
WikiUrSchool建置計畫WikiUrSchool建置計畫
WikiUrSchool建置計畫RueiCi Wang
 

More from RueiCi Wang (11)

李群在機器學習中的應用(超基礎篇)
李群在機器學習中的應用(超基礎篇)李群在機器學習中的應用(超基礎篇)
李群在機器學習中的應用(超基礎篇)
 
金融市場資料的區間分析法
金融市場資料的區間分析法金融市場資料的區間分析法
金融市場資料的區間分析法
 
如何打造社會企業:重點文摘
如何打造社會企業:重點文摘如何打造社會企業:重點文摘
如何打造社會企業:重點文摘
 
[US學習資料] 如何編列組織的預算?
[US學習資料] 如何編列組織的預算?[US學習資料] 如何編列組織的預算?
[US學習資料] 如何編列組織的預算?
 
如何推動新板Ur school網站前進
如何推動新板Ur school網站前進如何推動新板Ur school網站前進
如何推動新板Ur school網站前進
 
UrSchool 三分鐘搞懂願景
UrSchool 三分鐘搞懂願景UrSchool 三分鐘搞懂願景
UrSchool 三分鐘搞懂願景
 
台師大合作提案
台師大合作提案台師大合作提案
台師大合作提案
 
Urschoolbookv031
Urschoolbookv031Urschoolbookv031
Urschoolbookv031
 
成大校園團隊招募計畫
成大校園團隊招募計畫成大校園團隊招募計畫
成大校園團隊招募計畫
 
升學諮詢概念分享會
升學諮詢概念分享會升學諮詢概念分享會
升學諮詢概念分享會
 
WikiUrSchool建置計畫
WikiUrSchool建置計畫WikiUrSchool建置計畫
WikiUrSchool建置計畫
 

Recently uploaded

Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROmotivationalword821
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 

Recently uploaded (20)

Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTRO
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 

Writing Macros

  • 1. Writing Macros Chapter 8 of CLOJURE for the BRAVE and TRUE ( LINK : http://www.braveclojure.com/writing-macros/ ) 2016/8/11 - ClojureTW 讀書會 @ 摩茲工寮, 台北
  • 2. Macros Are Essential ● Macros are an integral part of Clojure development — they’re even used to provide fundamental operations. ● EXAMPLE: “ when ” = “ if ” + “ do ” ( macroexpand ‘( when boolean-expression expression-1 expression-2 expression-3)) ; => (if boolean-expression ; (do expression-1 ; expression-2 ; expression-3))
  • 3. Anatomy of a Macro Macros receive unevaluated, arbitrary data structures as arguments and return data structures that Clojure evaluates defmacro defn (evaluated)
  • 4. Building Lists for Evaluation ● Macro writing is all about building a list for Clojure to evaluate defmacro final list to evaluate unevaluated arguments
  • 5. Building Lists for Evaluation ● Macro writing is all about building a list for Clojure to evaluate (defmacro infix-2 [[operand1 op operand2]] (list op operand1 operand2))
  • 6. Building Lists for Evaluation ● You’ll need to be extra careful about the difference between a symbol and its value Macro (building lists) closed-box (list of symbol) Evaluation
  • 7. Building Lists for Evaluation ● You’ll need to be extra careful about the difference between a symbol and its value (defmacro my-print-whoopsie [expression] (list let [result expression] (list println result) result)) EXCEPTION
  • 8. Building Lists for Evaluation ● You’ll need to be extra careful about the difference between a symbol and its value (defmacro my-print-whoopsie [expression] (list 'let ['result expression] (list 'println 'result) result)) OK!
  • 9. Building Lists for Evaluation Single Quoting vs. Syntax Quoting '+ ; => + `+ ; => clojure.core/+ Syntax quoting will always include the symbol’s full namespace → Help you avoid name collisions
  • 10. Building Lists for Evaluation Single Quoting vs. Syntax Quoting '(+ 1 ~(inc 1)) ; => (+ 1 ~(inc 1)) `(+ 1 ~(inc 1)) ; => (clojure.core/+ 1 2) full namespace evaluated instead of being quoted!
  • 11. Building Lists for Evaluation Single Quoting vs. Syntax Quoting The other difference between quoting and syntax quoting is that the latter allows you to unquote forms using the tilde, ~ ( q u o t e d ) ‘ ( q u o t e d ` ~ ( evaluated ) q u o t e d )
  • 12. Using Syntax Quoting in a Macro If you want your macro to return multiple forms for Clojure to evaluate, make sure to wrap them in a do. (defmacro code-critic "Phrases are courtesy Hermes Conrad from Futurama" [bad good] `(do (println "Great squid of Madrid, this is bad code:" (quote ~bad)) (println "Sweet gorilla of Manila, this is good code:" (quote ~good))))
  • 13. Refactoring a Macro and Unquote Splicing (do ((clojure.core/println "criticism" '(1 + 1)) (clojure.core/println "criticism" '(+ 1 1)))) (do (nil nil)) EXCEPTION NullPointerException nil function nil argument Unquote splicing was invented precisely to handle this kind of situation
  • 14. Refactoring a Macro and Unquote Splicing `(+ ~(list 1 2 3)) ; => (clojure.core/+ (1 2 3)) `(+ ~@(list 1 2 3)) ; => (clojure.core/+ 1 2 3) Great ! (defmacro code-critic [{:keys [good bad]}] `(do ~@(map #(apply criticize-code %) [["Sweet lion of Zion, this is bad code:" bad] ["Great cow of Moscow, this is good code:" good]]))) do & map so convenient !
  • 15. Refactoring a Macro and Unquote Splicing ( q u o t e d ` ~ ( evaluated ) q u o t e d ) ( q u o t e d ) ‘ ( q u o t e d ` ~ ( evaluated ) q u o t e d )@ Unquote simple function simple function + do, map … etc.
  • 16. Things to Watch Out For 1. Variable Capture (def message "Good job!") (defmacro with-mischief [& stuff-to-do] (concat (list 'let ['message "Oh, big deal!"]) stuff-to-do)) (with-mischief (println "Here's how I feel about that thing you did: " message)) ; => Here's how I feel about that thing you did:Oh, big deal!
  • 17. Things to Watch Out For 1. Variable Capture Uncorrelated Macro letB -> C function ( input: A) ( output: A) function ( input: A) ( B ->C) ( output: A) function ( input: B) ( B ->C) ( output: C) B B B C
  • 18. Things to Watch Out For 1. Variable Capture (def message "Good job!") (defmacro with-mischief [& stuff-to-do] `(let [message "Oh, big deal!" ] ~@stuff-to-do)) (with-mischief (println "Here's how I feel about that thing you did: " message)) ; Exception: Can't let qualified name: user/message Syntax quoting is designed to prevent you from accidentally capturing variables within macros.
  • 19. Things to Watch Out For 1. Variable Capture (defmacro without-mischief [& stuff-to-do] (let [macro-message (gensym 'message)] `(let [~macro-message "Oh, big deal!" ] ~@stuff-to-do (println "I still need to say: " ~macro-message)))) (without-mischief (println "Here's how I feel about that thing you did: " message)) ; => Here's how I feel about that thing you did: Good job! (gensym 'message) ; => message4763 Symbol prefix ! This example avoids variable capture by using gensym to create a new, unique symbol that then gets bound to macro-variable.
  • 20. Things to Watch Out For 1. Variable Capture Uncorrelated Macro gensym let B -> C function ( input: A) ( output: A) function ( input: A) ( gensym B ->C) ( output: A) function ( input: B) ( B123 ->C) ( output: B) B B B B
  • 21. Things to Watch Out For 1. Variable Capture `(blarg# blarg#) (blarg__2869__auto__ blarg__2869__auto__) `(let [name# "Larry Potter" ] name#) ; => (clojure.core/let [name__2872__auto__ "Larry Potter"] name__2872__auto__) Because this is such a common pattern, you can use an auto-gensym. Auto-gensyms are more concise and convenient ways to use gensyms
  • 22. Things to Watch Out For ( q u o t e d ` ~ ( evaluated ) q u o t e d ) ( q u o t e d ` ~ ( evaluated ) q u o t e d )@ Unquote + do, map … etc. ( quoted ` ~ ( evaluated )( let [ var # … ] autogem
  • 23. Things to Watch Out For 2. Double Evaluation (defmacro report [to-try] `(if ~to-try (println (quote ~to-try) "was successful:" ~to-try) (println (quote ~to-try) "was not successful:" ~to-try))) 1 2 3
  • 24. Things to Watch Out For 2. Double Evaluation Repeated actions in Macro let repeat 100 times function ( input: A) a lot of calc ( output: A) function ( input: A) a lot of repeating calc ( output: A) B B B function ( input: A) a lot of repeating calc ( output: A) Waiting for calculation process ….
  • 25. Things to Watch Out For 2. Double Evaluation (defmacro report [to-try] `(if ~to-try (println (quote ~to-try) "was successful:" ~to-try) (println (quote ~to-try) "was not successful:" ~to-try))) 1 2 3 (defmacro report [to-try] `(let [result# ~to-try] (if result# (println (quote ~to-try) "was successful:" result#) (println (quote ~to-try) "was not successful:" result#)))) 1 Double eval ? → let → Var capture ? → auto-gensym
  • 26. Things to Watch Out For 3. Macros All the Way Down (doseq [code ['(= 1 1) '(= 1 2)]] (report code)) ; => code was successful: (= 1 1) ; => code was successful: (= 1 2) (defmacro doseq-macro [macroname & args] `(do ~@(map (fn [arg] (list macroname arg)) args))) (doseq-macro report (= 1 1) (= 1 2)) ; => (= 1 1) was successful: true ; => (= 1 2) was not successful: false report operating at macro expansion time, just can’t access those values. To resolve this situation, you might write another macro
  • 27. Things to Watch Out For 3. Macros All the Way Down ● It’s easy to paint yourself into a corner, making it impossible to accomplish anything with run-of-the-mill function calls. ● They only really compose with each other, so by using them, you might be missing out on the other kinds of composition (functional, object-oriented) available to you in Clojure. Macro Macro Macro Macro Macro Macro Macro Macro Macro Macro Macro Macro
  • 28. Summary Don’t listen to these prudes — at least, not at first! Go out there and have a good time. That’s the only way you’ll learn the situations where it’s appropriate to use macros. You’ll come out the other side knowing how to use macros with skill and panache.