这是对更好错误消息的另一个+1。
下面提到的库或多或少成功处理了症状,但让我们从一个想要学习Clojure的人的角度来考虑,因此他们前往Clojure.org,点击“入门”。
好的,我现在知道如何下载它。也许我会尝试使用repl.it
来感受一下。
现在我有了一个基本的感觉(带有clojure.org的令人困惑的错误消息)(见:“你可能看到的令人困惑的错误之一是意外尝试将数据列表作为代码评估的结果”)
那么,我们先从学习 Clojure 开始吧。
Ok,关于如何启动 REPL 的信息仍然没有。
第三个链接:以这种方式启动 REPL 是一个好主意。
第四个链接:这里有启动 REPL 的 n 种方法。
这里有其他运行 REPL 的方法。
没有人提到任何关于:如果你是初学者,让我们添加 clj-stacktrace,然后启动 REPL。
你看出为什么这是不实际的吗?
我知道你近年来付出了很多努力改进文档,我感到很难指出这些事情。很难回到这样熟悉的东西,并用一个想学习这门新语言的开发者的眼光来看待它。
我相信你只有1次或2次机会留下好印象和可读的错误信息,告诉用户哪里错了,这是很重要的一部分。
user=> (map 1 inc)
不知道如何从:clojure.core$inc 创建 ISeq
user=> (1 2 3)
执行错误 (ClassCastException) 在 user/eval7 (REPL:1) 处。类 java.lang.Long 无法转换为类 clojure.lang.IFn (java.lang.Long 位于模块 java.base 的加载器 'bootstrap';clojure.lang.IFn 位于未命名的模块的加载器 'app')
两者都没有告诉我我哪里做错了。它们告诉我在幕后 Lisp 解释器工作的某些细节。(其中一些在 clojure.org 上有文档记录)。
鉴于这些对初学者没有帮助,我将使用谷歌搜索。
对初学者来说,谷歌搜索错误消息的容忍度并不高,例如错误的参数顺序或调用无法调用的内容。
这就是为什么你会给人留下这样的印象,即引导用户错误的错误消息并不重要。
(顺便说一下,对于一个(nil 2 3)的处理已经很好,没有抛出 NPE)
这就是 Clojure(实现)积极参与“巨大的学习曲线”这一宗教的原因。
我不在乎我经历过这种错误很多次后,我学到了什么。(与 Sean 的评论有关)。
损害已经造成。
其他 Clojure 转义目前做得更好。(例如 CLJS 和 Sci)。
谈到努力:有一种反对意见认为提供更好的错误消息会影响性能。如果我们在这里谈论异常处理(在上面两种情况下我们确实是这样)
我不确定我是否理解到性能影响在哪里。
因为 s-expr 失败而进行的异常处理不是性能关键路径,我认为。
我愿意更好地了解性能方面是如何发挥作用的。
此外,仅仅就上述两个示例错误消息而言,从用户的视角而不是系统的视角编写它们,所付出的努力并不大。其中的一个意味着在 RT.java 的第 557 行进行更改
更好的错误消息可能意味着捕捉更底层的异常,将它们与当前 AST 关联,并以与生成错误列表元素关联的消息重新抛出。
我恳求您指导初学者走向他们可能获得的最佳 REPL。
在入门和了解 Clojure 时使其成为默认选项。
然后你可以拉回帷幕,说:你知道,下面是 IFn 和 ISeq,你可能会看到 Java 堆栈跟踪。
当你沿着 Clojure 路线走时,有很多新的概念需要学习和理解。错误消息的重解释不应该成为其中之一。