clojure - How Can I Use an Existing Vector in a :keys Destructuring -
currently have type them out literal list of symbols in :keys destructing in let binding.
(let [{:keys [title author]} arg-map] (println title)) but have list of keywords want destructure, , want use them in other places in program.
is there macro magic can reference symbol name in let binding rather have duplicate existing vector, making me have update same list multiple times if changes.
(def valid-keys [:title :author]) (let [{:keys valid-keys} arg-map] (println title)) thanks help.
absolutely
(def keywords [:title :author]) (defmacro with-valid-keys [m & forms] (let [syms (map (comp symbol name) keywords)] `(let [{:keys [~@syms]} ~m] ~@forms))) if have vector of keywords, can convert symbols , use them in let binding. macroexpand can see macro produces let binding symbols.
(prn (macroexpand-1 '(with-valid-keys {:title "hahaha"} (println title)))) => (clojure.core/let [{:keys [title author]} {:title "hahaha"}] (println title))
(with-valid-keys {:title "hahaha"} (println title)) => hahaha
be wary hiding bindings introduces problems:
- shadowing. had 'valid key' :name, in code used
namefunction insidewith-valid-keys, bound value of name, not function. - navigability. ides wont able identify symbol comes from.
Comments
Post a Comment