Простые, но убедительные примеры макросов, которых еще нет в Clojure - PullRequest
12 голосов
/ 14 сентября 2010

Я пытаюсь написать учебник по макросам, и теперь мне нужны примеры, которые просты для понимания и, тем не менее, убедительны.

Проблема в том, что многие очевидные вещи уже находятся в замешательстве и способствуют. И я чувствую, что «посмотрите, мы можем переопределить все библиотечные функции», возможно, не лучший аргумент, почему макросы так хороши.

У кого-нибудь есть какие-нибудь милые (однострочные) примеры, которые они не возражали бы мне использовать?

Вот первые три части урока. На данный момент это немного нелепо, поэтому любые комментарии о том, как это можно улучшить, будут с благодарностью приняты.

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

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

Ответы [ 2 ]

6 голосов
/ 14 сентября 2010

Я работаю над некоторыми криптографическими программами в ближайшем будущем. Это действительно весело, и использование юнит-тестирования делает его более увлекательным, потому что я не нервничаю, когда ломаю вещи. Проблема в том, что все крипто-функции каждый раз генерируют разные результаты, потому что они управляются довольно хорошим генератором псевдослучайных чисел IMHO.

Как проверить рандомизированные функции?

с макросом bind, конечно!

(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))

затем я обертываю свои тестовые функции в (with-fake-prng (deftest mytest ....))

У clojure много этих «макросов связывания». вроде with-out-string и тому подобное.

У меня также есть макрос, который загружает каждое пространство имен в repl. (Я не пользуюсь этим сейчас, когда перешел на торт)

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

ps: всегда помните первое правило макроклуба

4 голосов
/ 15 сентября 2010

Я бы больше поговорил о шаблонах: когда и как используется макрос. например ...

  • Защита ресурса. Примеры: binding, with-open, ...
    (let [~x (get-resource)] (try ~@dostuff (finally (release-resource ~x))))
  • Определение вещей. Примеры: defn, defsnippet (оживление), defservice (звонок)
  • Макро / разделение драйвера. Особенно эта техника снимает много макро боли. Как многократная оценка или захват. Пример: with-bindings
  • Украшать некрасивый код. например. когда Укрощение многомерных массивов
...