开发者

Simple Yet Compelling Macro Examples which are Not Already in Clojure

I'm trying to write a macro tutorial, and now I need some examples which are simple to understand, and yet compelling.

The problem is that a lot of the obvious things are already in clojure and contrib. And I feel that "look, we can reimplement all the library functions" might not be the best argument for why macros are so great.

Has anyone got any cute (one-liners are best) examples that they wouldn't mind me using?

Here are the first three parts of the tutorial. It's a bit ropy at the moment, so any comments about how it could be made better would be gratefully received.

http://learnclojure.blogspot.com/2010/09/clojure-macro-tutorial-part-i-getting.html

http://learnclojure.blogspot.com/2010/09/clojure-macro-tutorial-part-ii-compiler.html

开发者_StackOverflow社区http://learnclojure.blogspot.com/2010/09/clojure-macro-tutorial-part-ii-syntax.html


I'm working on some cryptography software in clojure. Its really fun and using unit testing makes it more fun because I don't get nervous about breaking things. The trouble is that all the crypto functions generate different results every time because they are driven by a fairly good IMHO psudo random number generator.

How do I test randomized functions?

with a bind macro of course!

(defmacro with-fake-prng [ & exprs ]
  "replaces the prng with one that produces consisten results"
  `(binding [com.cryptovide.split/get-prng (fn [] (cycle [1 2 3]))
             com.cryptovide.modmath/mody 719
             com.cryptovide.modmath/field-size 10]
       ~@exprs))

then I wrap my test functions in (with-fake-prng (deftest mytest ....))

clojure has a lot of these "bind macroes". like with-out-string and such.

I also have a macro that loads every namespace into the repl. (I dont use this much now that I have switched to cake)

(defmacro load-all []
  '(use 
   :reload-all
   'com.cryptovide.modmath
    ...  
   'com.cryptovide.gui
   'com.cryptovide.checksum
   'com.cryptovide.log))

ps: always mind the first rule of macro club


I would talk more about patterns: when and how is a macro used. eg...

  • Protecting a resource. Examples: binding, with-open, ...
    (let [~x (get-resource)] (try ~@dostuff (finally (release-resource ~x))))
  • Defining things. Examples: defn, defsnippet (enlive), defservice (ring)
  • Macro/driver split. Especially this technique takes away a lot of macro pain. Like multiple evaluation or capture. Example: with-bindings
  • Beautifying ugly code. eg. when Taming multi-dim arrays
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜