Another +1 for having even better error messages out of the box.
The libraries mentioned below are dealing with the symptoms somewhat successfully, but let's put ourselves in the shoes of someone wanting to learn Clojure, and thus turn to Clojure.org, click on Getting Started.
Alright, I now know how to download it. Perhaps I'll try it out using repl.it
.
Now I have the basics experience (with somewhat confusing error messages according to clojure.org (see: "A confusing error you might see is the result of accidentally treating a list of data as if it were code:"))
Well, let's go to Learn Clojure first.
Ok, still nothing about how to launch a 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的loader 'bootstrap'中;clojure.lang.IFn在未命名的模块的loader '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路径时,有很多新的概念要学习和理解。重新解释错误信息不应该是其中之一。