这里是对更好错误信息的另一个+1。
下面提到的库在某种程度上成功地处理了症状,但让我们从想要学习Clojure的人的角度来看,因此前往Clojure.org,点击入门。
好的,我现在知道如何下载它了。也许我会尝试通过使用repl.it
来感受一下。
现在我有了基本的经验(带有clojure.org中令人困惑的错误消息)(参见:“你可能会看到的令人困惑的错误之一是意外将数据列表作为代码尝试评估的结果:”)
那么,让我们先学习Clojure。
好的,仍然没有关于如何启动REPL的内容。
第三个链接:启动REPL是个好主意。
第四个链接:这里有n种启动REPL的方法。
这里有其他运行REPL的方法。
没有提到任何关于:如果你是初学者,让我们添加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')
两者都没有告诉我我做了什么错。它告诉我一些关于背后如何工作的lisp解释器的具体信息。(其中一些在clojure.org上有文档记载)。
由于这些对我这个新用户没有任何帮助,我只好在谷歌上搜索。
对于像错误的参数顺序或调用无法调用的东西这样的错误,初学者对搜索错误信息的容忍度并不高。
这就是你给人留下错误信息对用户不重要的印象的地方。
(顺便说一句,你已经在处理(nil 2 3)方面做得很好,并没有抛出NPE)
这就是clojure(实现)积极地促成了“巨大的学习曲线”这个说法。
这并不重要,因为我看到这个错误足够多了,我知道它是什么。(关于Sean的评论)。
损害已经造成了。
其他Clojure方言在这方面做得更好。(例如CLJS和Sci)。
说到努力:有一个反对意见认为,提供更好的错误信息会影响到性能。如果我们在这里谈论异常处理(在上述两种情况中都这样做),
我不太明白性能影响在哪里。
因为s表达式失败而进行的异常处理不是性能关键路径,我想。
我很乐意更好地理解性能方面是如何介入的。
此外,仅就上面的两个示例错误信息而言,从用户的角度编写它们——而不是从系统的角度——的努力并不高。其中一个是改变RT.java第557行
更好的错误信息可能意味着捕获低级别的异常,将它们与当前的AST关联,并以与生成错误的消息关联的列表元素重新抛出。
我恳求您引导初学者进入他们能达到的最好的REPL。
使其成为入门和学习Clojure的默认设置。
然后你可以拉上帘子说:你知道,下面有IFn和ISeq,你可能会看到Java堆栈跟踪。
当走Clojure的道路时,有很多新的概念需要学习和理解。重新解释错误信息不应该是其中之一。