对更好的错误消息表达支持。
下述提到的库基本上成功地处理了症状,但让我们从一个想学习Clojure的人的角度来看,他们前往Clojure.org,点击"入门"。
现在我知道如何下载它。也许我会尝试使用《repl.it》来感受它。
现在我有了最基本的体验(带有 clojure.org 混淆的错误消息)(见:"你可能看到的令人困惑的错误可能是由意外尝试将数据列表评估为代码而产生的:")
好,让我们首先去学习Clojure。
好,仍然没有什么关于如何启动REPL的信息。
第三个链接:启动REPL是个好主意。
第四个链接:这里有n种启动REPL的方法。
这里有其他运行REPL( Reads-Evaluates-Prints Loop,读取-计算-打印循环)的方法。
没有任何一种提到:如果你是初学者,让我们添加clj-stacktrace,然后启动REPL。
你明白这为什么不切实际吗?
我知道你近年来投入了很多精力来改进文档,我对此指出这些事项感到很抱歉。很难回到如此熟悉的事物,并以想要了解这种新语言的开发者的视角来看待它。
我相信你只有1到2次机会留下良好的印象,而可读的错误信息,可以告诉你哪里出错,这是其中很重要的一部分。
user=> (map 1 inc)
不知道如何从:clojure.core$inc创建ISeq。
user=> (1 2 3)
执行错误(ClassCastException)在用户/eval7(REPL:1)。类java.lang.Long不能转换为类clojure.lang.IFn(java.lang.Long存在于模块java.base的加载器'bootstrap'中;clojure.lang.IFn存在于未命名的模块的加载器'app'中)
这两个都没有告诉我我错在哪里。它只是告诉我后台如何工作的某些具体信息。(其中一些在clojure.org上有文档说明)。
由于所有这些对我来说都没有帮助,所以作为新用户,我将在谷歌中搜索。
对于初学者来说,像错误的参数顺序或调用无法调用的操作这样的错误,通过谷歌搜索错误消息的忍受度并不高。
这就是你给用户的印象,似乎错误信息引导用户并不重要。
(顺便说一句,奇怪的是,你已经很巧妙地处理了(nil 2 3),而没有抛出NPE)。
这就是Clojure(该实现)积极参与“巨大的学习曲线”这一神话的地方。
我在多次看到这个错误之后才了解到它是什么。(关于Sean的评论)。
损害已经造成。
其他Clojure方言在这里做得更好。(例如CLJS和Sci)。
说到努力:有一种反对意见认为提供更好的错误信息会影响性能。如果我们在这里谈论异常处理(并且在上面的两个案例中我们都在这样做),
我不是很明白性能影响在哪里。
由于s-expr失败而进行的异常处理不应该在性能关键路径上,我认为。
乐于更好地了解性能方面的作用。
仅对上面的两个示例错误消息而言,从用户的视角而不是系统的视角编写它们的精力并不大。对于其中之一,意味着更改RT.java中的第557行
更好的错误信息可能意味着捕获低级异常,将它们与当前的AST关联,并将它们重新抛出,与生成错误的列表元素关联的消息。
我恳请您引导初学者获得最好的REPL。
让这在入门和了解Clojure中成为默认的。
然后你可以拉回帘幕说:你知道,下面是IFn和ISeq,你可能会看到Java堆栈跟踪。
在沿着Clojure的道路前进时,有许多新的概念需要学习和理解。重新解释错误信息不应该是其中之一。