另一项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 < whatever > cannot be cast to clojure.lang.IFn...
之类的消息重写为易于理解的表述(例如Expected a function - found a < whatever>
)。
类似的动态钩子可以过滤堆栈帧,并将“打印”它们到字符串中,这将为初学者提供更友好的输出。