Thank you, Ken. It's encouraging to see the community is thinking of
ways to improve this.

On Aug 2, 6:39 am, Ken Wesson <kwess...@gmail.com> wrote:
> On Tue, Aug 2, 2011 at 3:11 AM, recurve7 <dan.m...@gmail.com> wrote:
> > Here's one example where recursion and lack of positional error
> > feedback make it hard for me, as someone coming from Java, to spot the
> > error (and seeing "ClassCastException" threw me off and had me
> > wondering where/how I had done something like that):
>
> > user=> (defn fac [n] (if (= n 1) 1 (* n fac (- n 1))))
> > #'user/fac
> > user=> (fac 3)
> > java.lang.ClassCastException: user$fac cannot be cast to
> > java.lang.Number (NO_SOURCE_FILE:0)
>
> This is saying that a "user$fac" was found where a number was
> expected. You have a function called fac in the user namespace -- this
> is "user$fac" to Java. So, you probably tried to perform arithmetic on
> a function. It's a math function, so you probably meant to call it and
> perform arithmetic on the result, and left out a pair of parentheses.
>
> It is true that the messages commonly encountered could stand to be
> better documented on a Clojure site. I'm wondering if we could go
> further, though, and make REPL exception printing more informative.
> The Java exception gets stored in *e, so someone can always type *e to
> retrieve it, or (.printStackTrace *e), etc., so printing an
> interpretation of the exception wouldn't render the raw exception
> inaccessible.
>
> This suggests trying to parse common exceptions into Clojurish
> messages; e.g. the above could be found to be a CCE, then the detail
> message parsed to extract the classnames; then a message pieced
> together based on those, e.g.
>
> java.lang.Number -> a number
> clojure.lang.Cons/LazySeq/PersistentList/etc. -> a list or seq
> clojure.lang.Vector -> a vector
> w.x$y when a function w.x/y exists -> the function w.x/y
> ...
>
> and the shallowest Clojure function before interop can be dug out of
> the stack trace, in the above case clojure.core/*, and the above
> message could then come out as
>
> Error: expected a number for *, but found the function user/fac instead.
>
> In the case it's a function in the wrong place, the addendum could be 
> generated:
>
> (Perhaps you meant to call the function, but left out a pair of parentheses.)
>
> The lack of line number information for errors in REPL evaluations is
> also an issue. I suggest that when a defn is evaluated at the REPL, it
> gets metadata like {:file REPL$user$fac :line 1} where the line number
> counts from the "defn" on down. The message printer can parse the file
> name from the exception and if it's REPL$anything parse it as
> referring to a REPL evaluation and not an actual file, printing
> something like "line 1 of user/fac" in the OP's instance. IDEs can
> also possibly have go-to-error pull up the relevant line in the REPL
> backbuffer, searching backwards for the most recent evaluation of
> (defn fac ...) in user for instance and then finding line 1 of that.
> When the error's in a normal source file, of course, existing behavior
> is adequate for the most part (though there are sometimes problems
> when macros are involved -- particularly, the line number is commonly
> the start of the macro body, though not oddly when that macro is
> "defn").
>
> Clooj would be a good place to experiment with a friendlier REPL error
> reporting system.
>
> --
> Protege: What is this seething mass of parentheses?!
> Master: Your father's Lisp REPL. This is the language of a true
> hacker. Not as clumsy or random as C++; a language for a more
> civilized age.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to