另一项Clojure发展现状调查和“错误信息”仍然是改进的首要任务。
在Slack上的讨论导致围绕异常和错误信息的一系列特定新手痛点。我想在此处关注的焦点是提供(pst)的入门友好替代品。
目前,(pst)在去混淆名称、消除“噪声”和缩小堆栈跟踪方面做出了合理的尝试--但它仍有许多值得期待的地方,对于那些努力理解某些异常并难以在(Java样式)堆栈跟踪中导航的新手来说更是如此,尤其是在与其他一些努力提供用户友好的错误信息和堆栈跟踪的语言相比。
Slack中的一个例子是
(defn f [i]
(fn [j]
(/ j i)))
(run! #(% 1) (map f (range 3)))
REPL中打印的异常没问题,但(pst)显示了
user=> (pst)
ArithmeticException Divide by zero
clojure.lang.Numbers.divide (Numbers.java:190)
user/f/fn--16571 (NO_SOURCE_FILE:3)
user/eval16576/fn--16577 (NO_SOURCE_FILE:1)
clojure.core/run!/fn--8906 (core.clj:7849)
...
省略部分指出了clojure.lang.ArrayChunk.reduce
并随后多次引用clojure.core.protocols
相关内容(默认不会过分深入地显示对clojure.core/run!
的原始调用)。
我认为这里有机会实现一个新的clojure.repl/explain
函数,它接受与(pst)相同的参数,提供了对失败更详细的解释,并进一步减少(pst)当前显示的堆栈跟踪中的噪声。
理想情况下,这可以通过在核心中进行一些基本的清理来实现,同时使用一些动态挂钩,允许其他工具“安装”额外的扩展和/或清理,从而使社区可以提供库和功能,进一步提高新手体验的这一方面。
例如,到ex-str
的动态挂钩将允许社区提供的工具调整显示的异常消息(既适用于原始REPL输入,也适用于(pst)和(explain)),使初学者难以理解的消息(例如class <something> cannot be cast to clojure.lang.IFn...
)可以被重写为新手友好的语言(期望函数 - 找到 <something>
)。
类似的动态挂钩可以过滤堆栈帧,并将它们“打印”到字符串中,为初学者提供更友好的输出。