Is there a way to print the result of evaluating nested syntax quotes in a legible manner as in SBCL? This would be useful when debugging nested syntax quotes when writing macros. For instance, in Clojure 1.8,
(let [x '(1 2)] ``(~~@x))
evaluates to
(clojure.core/seq (clojure.core/concat (clojure.core/list 1 2)))
In SBCL 1.3.6, the equivalent expression
(let ((x '(1 2))) ``(,,@x))
evaluates to the much more legible
`(,1 ,2)
The difference becomes larger with more complex expressions. Are there any Clojure packages or other methods that can help with this situation? Currently, the best way I've found to debug complex syntax quotes is to convert them to Common Lisp but this is a rather ridiculous and slow approach.
If you look the function syntaxQuote(Object form)in the LispReader Class of Clojure : https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L1011
ISeq seq = RT.seq(form);
if(seq == null)
ret = RT.cons(LIST,null);
else
ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));
you'll see that `(~@'(some list)) is read as :
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote clojure.core/some))
(clojure.core/list (quote clojure.core/list))))
Which is evaluated by the REPL as :
=> (some list)
Just look at the effect of ` alone
`s => user/s ; it's the ref of the symbol ok
``s
=> (quote user/s) ; it's the quoted ref
```s
=> (clojure.core/seq ; now we manage a back-tick on a list
(clojure.core/concat
(clojure.core/list (quote quote))
(clojure.core/list (quote user/s))))
````s
=>
(clojure.core/seq ; oups! always a list we add a layer
(clojure.core/concat
(clojure.core/list (quote clojure.core/seq))
(clojure.core/list
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote clojure.core/concat))
(clojure.core/list
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote clojure.core/list))
(clojure.core/list
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote quote))
(clojure.core/list (quote quote))))))))
(clojure.core/list
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote clojure.core/list))
(clojure.core/list
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote quote))
(clojure.core/list (quote user/s)))))))))))))
And now adding the splicing
````~s => (clojure.core/seq ; same as ```s
(clojure.core/concat
(clojure.core/list (quote quote))
(clojure.core/list (quote user/s))))
````~~s => (quote user/s) ; same as ``s
So what are the remarks to make
(quote s)
instead of 's
. This is done for arrays, set, ...The back-tick macro reader doesn't make simplification on list/quote matching. Concatenation of only quoted lists and single entries should be executed immediately, giving
````~~s => ''s.
The problem is that `s is not 's.
If I remember in LISP `s gives 's as a result. ;)
A possibility to manage a simplified version can be viewed so
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote quote))
(clojure.core/list (quote user/s))))
could be changed in the macro generation as
(seq 'user/s)
But!!! the result is a sequence, say a lazy sequence, not 'user/s
.
Let's try on ````s. simplifying would give :
(seq '(clojure.core/seq 'user/s))
The result is equivalent to ''s
, but it isn't the same object.
Another thing, we have to manage the toString
of (quote ...) as '...
And contrary to LISP 's
is s
and `s is user/s !!!
And for macro management, it makes a lot of changes... Say 's is in the execution namespace, `s is in the compilation namespace, executed by the reader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With