quoting vs syntax quoting

73 views
Skip to first unread message

Sonny To

unread,
Mar 2, 2020, 4:54:51 AM3/2/20
to Clojure
(defmacro moo1 []
  '(defn foo []))

(defmacro moo2 []                                                                                                                                                                                               
  `(defn foo []))

stigmergy.wocket.server> (moo1)                                                                                     
#'stigmergy.wocket.server/foo   
                                                                                   
stigmergy.wocket.server> (moo2)                                                                                     
CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/defn did not conform to spec:                    
In: [0] val: stigmergy.wocket.server/foo fails spec: :clojure.core.specs.alpha/defn-args at: [:args :name] predicat\
e: simple-symbol?                                                                                                   
 #:clojure.spec.alpha{:problems [{:path [:args :name], :pred clojure.core/simple-symbol?, :val stigmergy.wocket.ser\
ver/foo, :via [:clojure.core.specs.alpha/defn-args :clojure.core.specs.alpha/defn-args], :in [0]}], :spec #object[c\
lojure.spec.alpha$regex_spec_impl$reify__2436 0x33d84248 "clojure.spec.alpha$regex_spec_impl$reify__2436@33d84248"]\
, :value (stigmergy.wocket.server/foo []), :args (stigmergy.wocket.server/foo [])}, compiling:(*cider-repl workspac\
e/clj-collage:localhost:39319(clj)*:131:26)            

stigmergy.wocket.server> (macroexpand-1 '(moo1))                      
(defn foo [])   

stigmergy.wocket.server> (macroexpand-1 '(moo2))                      
(clojure.core/defn stigmergy.wocket.server/foo [])   




moo1 uses normal quoting while moo2 uses syntax quoting. Why does (moo1) succeeds but( moo2) fails? Both seem to evaluate to same data-structure except moo2 has namespaces.

The error message is cryptic but it seems moo2 is failing on clojure.core/simple-symbol? which seems like a symbol without a namespace.  How can I make a symbol without a namespace in syntax quoting?




Anatoly Smolyaninov

unread,
Mar 2, 2020, 5:39:02 AM3/2/20
to Clojure
Yes, backtick is hygienic, i.e. it adds ns to symbols. you can define name first and inject: 

```
(defmacro moo2 []
  (let [name (symbol "foo")]
    `(defn ~name [])))

```

понедельник, 2 марта 2020 г., 10:54:51 UTC+1 пользователь Sonny To написал:

Rutvik Patel

unread,
Mar 2, 2020, 7:49:38 AM3/2/20
to clo...@googlegroups.com
> How can I make a symbol without a namespace in syntax quoting?
You need quote + unquote. 

user=> (defmacro moo2 [] `(defn ~'foo []))
#'user/moo2
user=> (macroexpand-1 '(moo2))
(clojure.core/defn foo [])
user=> (moo2)
#'user/foo

Focus on ~'foo thing, we first quote the foo and unquote is using ~.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/82bdc4fc-2453-4561-80da-e3c6d6346900%40googlegroups.com.

Alan Thompson

unread,
Mar 2, 2020, 9:15:07 AM3/2/20
to clojure
It is even simpler if you just run the following code:

(println "plain-quote:   " 'map)
(println "syntax-quote: " `map)

with result:

plain-quote:    map
syntax-quote:   clojure.core/map

The syntax-quote also allows you to unquote forms using `~` and `~@` (you can't do this with plain-quote).  The combination allows you to easily make code templates, the same way you might make HTML templates with Selmer, Django, etc.

For full details of macro writing, please see this answer:  https://stackoverflow.com/questions/60212576/how-do-i-write-a-clojure-threading-macro

Alan

P.S.  Note that you can use syntax quote in regular functions as a trick to easily fully-qualify symbol names.  It is not only for macros.



Reply all
Reply to author
Forward
0 new messages