clojure - How do I pass a variadic macro to a function? -
i attempting learn clojure , having trouble macros. have simple macro:
(defmacro add [& x] `(apply + (list ~@x))) and have function can call multiple operations (add, subtract, multiply, , divide). these stdin simplicity have created variable holding list of numbers:
(defn do-op [op] (def numbers (list 1 2 3)) (apply op numbers)) in order call do-op appropriate operation need pass macro do-op in anonymous function:
(do-op #(add %&)) when run code using arguments passed stdin confusing error:
cannot cast clojure.lang.chunkedcons java.lang.number when execute in repl get:
cannot cast clojure.lang.persistentlist java.lang.number i assume has lack of understanding of how these variadic arguments getting handled thoroughly stumped. missing?
you can never ever pass macro if function, since doesn't exist after code compiled , ready run.
when have;
(do-op #(add %&)) ; shorthand (do-op (fn [& rest] (add rest))) ; expand macro (do-op (fn [& rest] (apply + (list (unquote-splice 'rest)))) ; how unsplice symbol rest separate elements? the short answer rest can never unspliced , using macro wrong. seems making alias + , can done making function or making binding original:
(defn add [& args] (apply + args)) ; making function calls + arguments (def add +) ; or make binding pointing same function + points (do-op add) ; ==> 6 you should keep using functions abstraction. whenever need write verbose, cannot make function because of evaluation, have candidate macro. translates shorter way write long verbose way write without knowing actual data types behind variable symbols, since compiler won't know when expanding macro. macro gets expanded once, while function had macro might executed many times.
edit
in pastebin code can confirm never ever need macro:
(cond (= 1 option) (do-op #(add %&)) ...) should be
(cond (= 1 option) (do-op +) ...) no need wrap or make macro this. pass function , want.
Comments
Post a Comment