这又是对于默认情况下更好的错误信息的一个+1。
下面提到的库在某种程度上成功地处理了症状,但从想要学习 Clojure 的人的角度来看,我们应该先看看 Clojure.org 上的“入门”部分。
好吧,现在我知道了如何下载它。也许我会尝试通过使用 repl.it
来试探一下它的感觉。
现在我有了基本的经验(使用 clojure.org 上令人困惑的错误消息 — 见:“一个令人困惑的错误可能是由于不小心将数据列表当作代码来评估所引起的”)
好吧,让我们先学习 Clojure。
好吧,仍然没有关于如何启动 REPL 的信息。
第三个链接:启动 REPL 是一个好主意。
第四个链接:这里有启动 REPL 的 n 种方法。
这里有其他运行REPL的方法。
没有提到如果你是初学者,我们可以添加clj-stacktrace,然后启动REPL。
你看到为什么这不太实际了吗?
我知道你在过去几年里为完善文档付出了很多努力,我指出这些问题很抱歉。回到如此熟悉的事物,并用一个想要学习这种新语言的开发者的眼光来看,是很困难的。
我相信你有一次或两次机会留下良好的第一印象和容易阅读的错误消息,而这些错误消息告诉你哪里出错,是其中重要的一部分。
用户=> (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中;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的道路上,有很多新的概念需要学习和理解。重新解释错误消息不应是其中之一。