We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(ns ^{:author "Jiacai Liu" :doc "https://segmentfault.com/l/1500000012556115"} demo.macro) ;; quote syntax-quote unquote splicing-unquote ;; 控制 symbol/list 求值时的行为 (let [x '(* 2 3) y x] (println `y) (println ``y) (println ``~y) (println ``~~y) (println (eval ``~~y)) (println `(~@y)) (println `(~y))) (defmacro nothing [params] (println params (type params))) (nothing x) ;; 一个简单的宏使用示例 (macroexpand-1 '(when (even? (rand-int 100)) (println "good luck!") (println "lisp rocks!"))) ;; 辅助函数 (defn prime? [n] (let [guard (int (Math/ceil (Math/sqrt n)))] (loop [i 2] (if (zero? (mod n i)) false (if (= i guard) true (recur (inc i))))))) (defn next-prime [n] (if (prime? n) n (recur (inc n)))) ;; do-primes 基本形式 (defmacro do-primes [[variable start end] & body] `(loop [~variable ~start] (when (< ~variable ~end) (when (prime? ~variable) ~@body) (recur (next-prime (inc ~variable)))))) ;; (doseq [a (range 10)] ;; (println a)) (do-primes [n 2 (rand-int 10)] ;; [2, 13) (println n)) (def start 1) ;; 使用 gensym 保证宏卫生 (defmacro do-primes2 [[variable start end] & body] `(let [start# ~start end# ~end] (loop [~variable start#] (when (< ~variable end#) (when (prime? ~variable) ~@body) (recur (next-prime (inc ~variable))))))) (do-primes2 [n 2 (rand-int 10)] ;; [2, 13) (println n)) (defmacro do-primes2-danger [[variable start end] & body] `(let [inner-start ~start inner-end ~end] (loop [~variable inner-start] (when (< ~variable inner-end) (when (prime? ~variable) ~@body) (recur (next-prime (inc ~variable))))))) (macroexpand-1 '(do-primes2 [n 2 (+ 10 (rand-int 30))] (println n))) (do-primes2-danger [n 2 (+ 10 (rand-int 30))] (println n)) ;; ~(quote inner-start) (defmacro do-primes2-safe [[variable start end] & body] `(let [~'inner-start ~start ~'inner-end ~end] (loop [~variable ~'inner-start] (when (< ~variable ~'inner-end) (when (prime? ~variable) ~@body) (recur (next-prime (inc ~variable))))))) (do-primes2-safe [n 2 (+ 10 (rand-int 30))] (println n)) ;; 宏嵌套宏 (defmacro only-once [names & body] (let [gensyms (repeatedly (count names) gensym)] (println "mmm") `(let [~@(interleave gensyms (repeat '(gensym)))] (println "nnn") `(let [~~@(mapcat #(list %1 %2) gensyms names)] (println "xxx") ~(let [~@(mapcat #(list %1 %2) names gensyms)] (println "yyy") ~@body))))) (defmacro do-primes3 [[variable start end] & body] (only-once [start end] `(loop [~variable ~start] (when (< ~variable ~end) (when (prime? ~variable) ~@body) (recur (next-prime (inc ~variable))))))) (do-primes3 [n 2 (+ 10 (rand-int 30))] (println n)) ;; 使用辅助函数来定义宏 (defmacro def-watched [name & value] `(do (def ~name ~@value) (add-watch (var ~name) :re-bind (fn [~'key ~'r old# new#] (println '~name old# " -> " new#))))) (def-watched foo 1) (def foo 2) (defmacro gen-watch-fn [name] (fn [k r o n] (println name ":" o " -> " n))) (defmacro def-watched2 [name & value] `(do (def ~name ~@value) (add-watch (var ~name) :re-bind (gen-watch-fn '~name)))) (def-watched2 bar 1) (def-watched2 bar 2)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
The text was updated successfully, but these errors were encountered: