Clojure 漂亮的打印嵌套语法引号
是否有一种方法可以像在SBCL中那样以清晰的方式打印嵌套语法引号的计算结果?这在编写宏时调试嵌套语法引号时非常有用。例如,在Clojure 1.8中Clojure 漂亮的打印嵌套语法引号,clojure,quote,Clojure,Quote,是否有一种方法可以像在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) 表达式越复杂,差异越大。
(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软件包或其他方法可以帮助解决这种情况?目前,我发现调试复杂语法引号的最佳方法是将它们转换为通用Lisp,但这是一种相当荒谬且缓慢的方法。如果您查看Clojure的LispReader类中的函数syntaxQuote(对象形式): 您将看到“(~@”(somelist))被理解为:
(clojure.core/seq
(clojure.core/concat
(clojure.core/list (quote clojure.core/some))
(clojure.core/list (quote clojure.core/list))))
REPL将其评估为:
=> (some list)
只要看看“孤独”的效果就知道了
`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
那么,你要说些什么呢
(引号s)
,而不是的
。这是针对数组、集合、(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))
结果相当于”的
,但它不是同一个对象
另一件事,我们必须将(quote…)的toString
管理为“
与LISP相反,的
是s
,`s是用户
对于宏管理,它进行了很多更改…例如,s在执行命名空间中,`s在编译命名空间中,由读取器执行。我假设您的意思是
`(一些列表)
,而不是`(一些列表)
。这可以计算为`(clojure.core/some clojure.core/list)
。符号解析不是问题,因为符号是完全限定的。@Qudit我修改了响应以更准确地理解问题。Clojure确实从嵌套的语法引号生成了非常难看的代码,但没有根本原因(或一个漂亮的打印语法引号包)不能再像SBCL那样做了。语法引号只需要扩展到以某种方式运行的代码。Clojure为此目的生成的特定代码没有什么特别之处。我添加了som补充内容,因为在注释中格式不可读。我希望我没有错过解释,可能会有点混乱。这就是为什么宏观管理会导致不明显的问题。backtick是一个reader宏,所以转换是在读取时完成的,编译后的宏已经有了转换的内容,如果有多个嵌套级别,这可能会让人混淆。引用不存在。。。它只是一个值,引用是给程序员的,程序就是这个值。
(seq '(clojure.core/seq 'user/s))