gpt4 book ai didi

clojure - pretty-print 嵌套语法引号

转载 作者:行者123 更新时间:2023-12-04 21:34:53 24 4
gpt4 key购买 nike

有没有办法像 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,但这是一种相当荒谬且缓慢的方法。

最佳答案

如果您查看 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)));

你会看到 `(~@'(some list)) 读作:
(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

那么有哪些注意事项
  • Clojure 编写器不会呈现读取器宏接收到的引号
    所以它给 (quote s)而不是 's .这是为数组、集合、...完成的。
  • 反引号宏阅读器不会简化列表/引用匹配。应立即执行仅引用列表和单个条目的串联,从而给出

    ````~~s => 's。
  • 如果您管理列表、数组或集合的反引号,问题会更糟... ;)

  • 问题是 `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 of (quote ...) as '...

    与 LISP 相反 'ss和`s 是用户/s !!!

    而对于宏管理,它做了很多改变...... Say 's 在执行命名空间中,`s 在编译命名空间中,由读者执行。

    关于clojure - pretty-print 嵌套语法引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40823656/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com