Reputation: 3814
I have created a macro in clojure
(ns macro-question.map)
(defmacro lookup [key] (list get (apply hash-map (range 1 5)) key))
in the clojure repl it works as expected
$ clj
Clojure 1.9.0
user=> (require 'macro-question.map)
nil
user=> (macro-question.map/lookup 1)
2
So I create a clojurescript module like this to try to use it:
(ns macro-question.core (:require-macros [macro-question.map]))
(defn lookup1 [] (macro-question.map/lookup 1))
and when I try that in the repl, I get this
$ clj -m cljs.main --repl-env node
ClojureScript 1.10.520
cljs.user=> (require 'macro-question.core)
Execution error (ExceptionInfo) at cljs.compiler/fn (compiler.cljc:304).
failed compiling constant: clojure.core$get@3df1a1ac; clojure.core$get is not a valid ClojureScript constant.
meanwhile back in clojure, there is a clue why this might be
user=> (macroexpand '(macro-question.map/lookup 1))
(#object[clojure.core$get 0x101639ae "clojure.core$get@101639ae"] {1 2, 3 4} 1)
I can create macros that start with '(
instead of (list
. However, I want the map to be expanded at build time.
What is going on? And what do I have to do to get something like the following:
user=> (macroexpand '(macro-question.map/lookup 1))
(get {1 2, 3 4} 1)
or what should I be doing to use this macro in clojurescript?
Upvotes: 2
Views: 295
Reputation: 3814
You can just put 'get
!!
(ns macro-question.map)
(defmacro lookup [key] (list 'get (apply hash-map (range 1 5)) key))
(https://stackoverflow.com/posts/58985564 is a better answer about why it happens, and a much better way to do it. This just shows a simple solution that only solves the immediate issue, that I realised right after I had asked the question)
Upvotes: 1
Reputation: 1904
(list get (apply hash-map (range 1 5)) key)
Creates a list where the first position is the function object that the var get
refers to. What you actually want to return is a list with the fully qualified symbol for get
as the first position. Change your macro definition to
(defmacro lookup [key]
`(get ~(apply hash-map (range 1 5)) ~key))
(macroexpand '(lookup 1))
=> (clojure.core/get {1 2, 3 4} 1)
The reference guide for the reader is helpful here https://clojure.org/reference/reader
Upvotes: 1