有没有办法以SBCL中的清晰方式打印评估嵌套语法引号的结果?在编写宏时,在调试嵌套语法引号时,这将非常有用。例如,在Clojure 1.8中,
(let [x '(1 2)] ``(~~@x))
评估为
(clojure.core/seq (clojure.core/concat (clojure.core/list 1 2)))
在SBCL 1.3.6中,等效表达式
(let ((x '(1 2))) ``(,,@x))
评估更清晰
`(,1 ,2)
表达式越复杂,差异越大。是否有任何Clojure软件包或其他方法可以帮助解决这种情况?目前,我发现调试复杂语法引用的最好方法是将它们转换为Common Lisp,但这是一种相当荒谬和缓慢的方法。
答案 0 :(得分:1)
如果你在Clojure的LispReader类中查看函数syntaxQuote(Object form): 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)));
你会看到`(〜@'(某些列表))被读作:
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote clojure.core/some))
(clojure.core/list (quote clojure.core/list))))
由REPL评估为:
=> (some list)
看看`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)))))))))))))
现在添加拼接
````~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
那么要做什么呢?
(quote s)
而不是's
。这是针对数组,set,... back-tick宏读取器不会对列表/引用匹配进行简化。应该立即执行仅引用列表和单个条目的连接,给出
````~~ s => '' S
问题在于,不是。
如果我记得在LISP中给出了结果。 ;)
可以查看管理简化版本的可能性
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote quote))
(clojure.core/list (quote user/s))))
可以在宏生成中更改为
(seq 'user/s)
但是!!!结果是一个序列,比如一个懒惰的序列,而不是'user/s
。
让我们试试```s。简化会给出:
(seq '(clojure.core/seq 'user/s))
结果相当于''s
,但它不是同一个对象。
另外,我们必须将toString
(引用...)作为'...
与LISP相反's
是s
而且`s是user / s !!!
对于宏管理,它进行了很多更改...... Say在执行命名空间中,`s在编译命名空间中,由读者执行。