On Tue, Aug 2, 2011 at 12:11 AM, recurve7 <[email protected]> wrote:
> 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) > Let's assume you'd put the code in a source file and run that. Now you'll get: java.lang.ClassCastException: user$fac cannot be cast to java.lang.Number (fac.clj:1) Where line 1 of fac.clj is: (defn fac [n] (if (= n 1) 1 (* n fac (- n 1)))) I'm not sure the positional information is all that helpful when there's only one line of code so let's look at the exception itself: user$fac cannot be cast to java.lang.Number The REPL told us we defined #'user/fac so that's our user$fac piece. We're using it in (* n fac (- n 1)) so that must be where the compiler is expecting a number instead of fac. What is that expression? It has a function * and three arguments: n, fac, (- n 1). n and (- n 1) are numbers but fac is not (it's a Clojure function - user$fac). So what's wrong? It looks like parentheses are missing in that expression and it should be a nested call to fac instead of a use of the value of fac: (* n (fac (- n 1))) I've been monitoring the Java Ranch forum on Clojure and omitting parentheses seems to be a fairly common mistake folks make when coming from Java. I guess that the parentheses being in the unfamiliar position before the function makes it easy to write func args instead of (func args), especially if args is already an expression like (- n 1)? Given the prefix nature of Lisp syntax, when confronted with (func arg1 arg2 arg3), as long as func can take three arguments, the compiler is only going to be able to give a type mismatch error (at best) if any of those arguments can't be converted to an obvious type (and Clojure's general lack of compile-time checking means you'll get runtime casting errors). Coming from a Java background, that's doubly hard to understand because a) the type checking is done at runtime and b) many functions can take an arbitrary number of arguments. It's really not a flaw with Clojure's compiler, nor something that it can do much about, but it gets much easier to figure out once you've spent more time with the language. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Railo Technologies, Inc. -- http://www.getrailo.com/ "Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en
