这里又对更好的默认错误消息投了一票。
下面提到的库在更多或更少的程度上成功地处理了症状,但让我们从一个想要学习Clojure的人的角度来看,他们会前往clojure.org,点击“入门”。
好吧,我现在知道如何下载它。也许我会尝试使用repl.it
来感受一下。
现在我有了基本的经验(根据clojure.org,含糊不清的错误消息)(参见:“可能会看到的一个令人困惑的错误消息是意外将数据列表当作代码尝试进行评估的结果:”)
好吧,我们先去学习柯华(Clojure)。
好吧,仍然没有关于如何启动REPL的信息。
第三链接:启动REPL是个好主意。
第四链接:这里有启动REPL的n种方式。
这里是其他启动REPL的方法。
没有提到以下几点:如果你是初学者,让我们添加clj-stacktrace,然后启动REPL。
你看到为什么这不太实用了吗?
我知道你最近几年对更好的文档投入了大量精力,我对此表示抱歉。很难回到这样熟悉的事物,并以一个想要了解这种新语言的开发者的眼光来看待。
我相信你有一次或两次机会给人留下好印象,让人们感兴趣的可读错误消息告诉他们哪里出了问题,这是其中重要的一部分。
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之路时,有很多新概念要学习和理解。重新解释错误消息不应该是其中之一。