我已经在http://lisperati.planvita.com/阅读了“casting SPELs”教程,它的俄文版本适用于 clojure ...到目前为止,我无法理解以下宏是如何工作的:(参见http: //lisperati.planvita.com/actions.html用于俄语版本或http://lisperati.com/actions.html用于 Lisp 的原始版本):
(defspel game-action [command subj obj place & args]
`(defspel ~command [subject# object#]
`(spel-print (cond (and (= location '~'~place)
(= '~subject# '~'~subj)
(= '~object# '~'~obj)
(have? '~'~subj))
~@'~args
:else '(i cannot ~'~command like that -)))))
它被进一步使用,如:
(game-action weld chain bucket attic
(cond (and (have? 'bucket) (def chain-welded true))
'(the chain is now securely welded to the bucket -)
:else '(you do not have a bucket -)))
(game-action dunk bucket well garden
(cond chain-welded
(do (def bucket-filled true)
'(the bucket is now full of water))
:else '(the water level is too low to reach -)))
这里 defspel - 只是 defmacro 的别名。
创建宏的原因是替换以下函数:
(defn weld [subject object]
(cond (and (= location 'attic)
(= subject 'chain)
(= object 'bucket)
(have? 'chain)
(have? 'bucket)
(not chain-welded))
(do (def chain-welded true)
'(the chain is now securely welded to the bucket -))
:else '(you cannot weld like that -)))
(defn dunk [subject object]
(cond (and (= location 'garden)
(= subject 'bucket)
(= object 'well)
(have? 'bucket)
chain-welded)
(do (def bucket-filled true)
'(the bucket is now full of water))
:else '(you cannot dunk like that -)))
我对这个“游戏动作”宏的工作方式完全感到困惑......有人可以向我解释所有关于它的事情(嵌套引号)吗?
我已经阅读了以下文章 - http://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html - 它没有帮助......
macroexpand-1 也吓到我了...
这是焊接游戏动作的输出:
(clojure-magic-game.core/defspel 焊接 [subject_ 1058 _auto__ object_ 1059 _auto_] (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure-magic-game.core/spel-print)) (clojure.core/list (clojure.core/seq (clojure.core /concat (clojure.core/list (quote clojure.core/cond)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/and))) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/=))) (clojure.core/list (quote clojure-magic-game.core/location )) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote attic)))))))))) (clojure .core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/=)) (clojure.core/list (clojure.core/seq (clojure.core/concat ( clojure.core/list (quote quote)) (clojure.core/list subject _1058_auto _)))) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote))) (clojure.core/list (quote chain)))))) )) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/=))) (clojure.core/list (clojure.core/seq (clojure. core/concat (clojure.core/list (quote quote)) (clojure.core/list object_1059_auto__)))) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote))) (clojure.core/list (quote bucket))))))) ) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure-magic-game.core/have?))) (clojure.core/list (clojure.core/ seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote chain))))))))))) (quote ((cond (and (have?) bucket)) (def chain-welded true)) (quote (链条现在已牢固地焊接在水桶上 -)) :else (quote (你没有水桶 -)))))) (clojure.core/list : else) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (引用 )) (clojure.core/list (clojure.core/seq (clojure.core/concat ( clojure.core/list (quote clojure-magic-game.core/i)) (clojure.core/list (quote clojure-magic-game.核心/不能))(clojure.core/list(引用焊接))(clojure.core/list(引用clojure-magic-game.core/like))(clojure.core/list(引用clojure-magic-game.core /that)) (clojure.core/list (quote clojure.core/-))))))))))))))
即使删除所有名称空间并缩进输出它仍然看起来太复杂而无法理解:
(defspel weld [subject__1058__auto__ object__1059__auto__]
(seq (concat
(list (quote spel-print))
(list (seq (concat
(list (quote cond))
(list (seq (concat
(list (quote and))
(list (seq (concat
(list (quote =))
(list (quote location))
(list (seq (concat
(list (quote quote))
(list (quote attic))))))))
(list (seq (concat (list (quote =))
(list (seq (concat
(list (quote quote))
(list subject__1058__auto__))))
(list (seq (concat
(list (quote quote))
(list (quote chain))))))))
(list (seq (concat
(list (quote =))
(list (seq (concat
(list (quote quote))
(list object__1059__auto__))))
(list (seq (concat
(list (quote quote))
(list (quote bucket))))))))
(list (seq (concat
(list (quote have?))
(list (seq (concat
(list (quote quote))
(list (quote chain)))))))))))
(quote ((cond
(and
(have? (quote bucket))
(def chain-welded true))
(quote (the chain is now securely welded to the bucket -))
:else (quote (you do not have a bucket -)))))
(list :else)
(list (seq (concat
(list (quote quote))
(list (seq (concat
(list (quote i))
(list (quote cannot))
(list (quote weld))
(list (quote like))
(list (quote that))
(list (quote -))))))))))))))