Clojure宏剖析

http://bryangilbert.com/blog/2013/07/30/anatomy-of-a-clojure-macro/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;; Before
(->>> 1
(+ _ 2)
(+ 3 _)
(- 50 _)
(/ _ 2))

;; After (macroexpansion)
(let [init 1]
(let [res0 (+ init 2)]
(let [res1 (+ 3 res0)]
(let [res2 (- 50 res1)]
(let [res3 (/ res2 2)]
res3)))))
1
2
3
4
5
6
7
8
9
10
11
  (defn convert-forms [val [next-form & other-forms]]               ; 1
(if (nil? next-form) ; 2
val
(let [next-val (gensym)] ; 3
`(let [~next-val ~(replace-underscores next-form val)] ; 4
~(convert-forms next-val other-forms))))) ; 5

(convert-forms 2 '((+ _ 1) (+ 4 _))) ; =>
; (clojure.core/let [G__1166 (+ 2 1)]
; (clojure.core/let [G__1167 (+ 4 G__1166)]
; G__1167))
1
2
3
4
1) 2=val, '((+ _ 1) (+ 4 _)) = [next-form & other-forms]
其中next-form=(+ _ 1), other-forms=(+ 4 _)

next-form != nil,

文章目录