这是对拥有更好的开箱即用错误信息的另一个支持。
以下提到的库在处理症状方面或多或少成功地处理了这些问题,但让我们从一个想要学习Clojure的人的角度来看,因此他们访问Clojure.org,点击“入门”。
好了,现在我知道如何下载它。也许我会尝试通过使用 repl.it
来感受它。
现在我有了一个基本的经验(带有clojure.org中令人困惑的错误消息)(见:“你可能会意外尝试将数据列表作为代码评估,产生的令人困惑的错误”)
总之,让我们先学习Clojure。
好了,关于如何启动REPL,还是一无所知。
第三个链接:启动REPL是一个好主意。
第四个链接:这里有 n 种启动 REPL 的方法。
这里还有其他运行 REPL 的方法。
没有一个提到:如果你是初学者,让我们添加 clj-stacktrace,然后启动一个 REPL。
你看到这是不切实际的原因了吗?
我知道你近年来在编写更好的文档方面付出了很多努力,我不忍指出这些事情。很难回到如此熟悉的事物,并以想要学习这门新语言的开发者的眼光来看它。
我相信你有一次或可能两次机会给人留下好印象,并且能够让用户读得懂的错误信息告诉我们哪里出错,这是其中一个重要部分。
user=> (map 1 inc)
不知道如何从 clojure.core$inc 创建 ISeq
user=> (1 2 3)
执行错误(ClassCastException)在 user/eval7(REPL:1)。class java.lang.Long 不能转换为 class clojure.lang.IFn(java.lang.Long 在 java.base 模块中;clojure.lang.IFn 在未命名的模块中)
这两者都没有告诉我我哪里做错了。它们只是告诉我一些关于 Lisp 解释器在幕后如何工作的细节。(其中一些已经记录在 clojure.org 上)。
由于这些对我不太有帮助,我是新用户,我将去谷歌搜索。
对于初学者来说,谷歌搜索错误信息(如参数顺序错误或尝试调用无法调用的方法)的容忍度并不高。
这就是你留下错误信息指引用户不重要的印象的地方。
(顺便说一句,奇怪的是,你处理 (nil 2 3) 比较好,并没有抛出 NPE)
这就是 Clojure(实现)积极参与到“巨大的学习曲线”这一说法的原因。
虽然我经常看到这个错误,但我已经学会了它的意思。(关于 Sean 的评论)
损害已经造成了。
其他 Clojure 方言在这里做得更好。(例如 CLJS 和 Sci)。
说到努力:有一种反对意见认为提供更好的错误信息会影响性能。如果我们在这里谈论异常处理(以及上述两种情况都是如此),
我不清楚性能影响在哪里。
由于 s-expr 失败而进行的异常处理不应该是在性能关键路径上的,我想。
我很高兴更好地理解性能方面如何发挥作用。
仅就上述两个示例错误信息而言,从用户的视角而不是系统的视角编写它们的努力并不大。对于其中的一个来说,意味着更改 RT.java 中的第 557 行。
更好的错误信息可能意味着捕获更底层的异常,将它们与当前的 AST 关联,并以与产生错误的消息元素相关的消息重新抛出。
我恳请你们引导初学者获得最好的 REPL。
让这个默认的入门步骤和学习 Clojure。
然后你可以说:你知道,下面是 IFn 和 ISeq,你可能看到 Java 堆栈跟踪。
在 Clojure 路径上,有许多新概念需要学习和理解。重新解释错误信息不应该是其中之一。