On Jun 19, 11:45 am, Rich Hickey <richhic...@gmail.com> wrote: > On Jun 19, 2010, at 4:25 AM, Daniel wrote: > > > > > Checked out the new prim branch to repeat some tests. > > > user=> (defn ^:static fib ^long [^long n] > > (if (<= n 1) > > 1 > > (+ (fib (dec n)) (fib (- n 2))))) > > #'user/fib > > user=> (time (fib 38)) > > "Elapsed time: 4383.127343 msecs" > > 63245986 > > > That's certainly not what I expected.... > > > user=> (defn fact [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n) > > (*' r n))))) > > #'user/fact > > user=> (fact 40) > > java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to > > java.lang.Number (NO_SOURCE_FILE:7) > > > Neither is this. According to the docs "long-and-smaller integers > > promote in all cases, even when given integer primitives" with the > > prime ops. > > > Something I did wrong? > > Yes, you are in the wrong branch. Get the 'equal' branch. > > Rich
Cool. This works correctly now. Super nice, too :) user=> (defn ^:static fib ^long [^long n] (if (<= n 1) 1 (+ (fib (dec n)) (fib (- n 2))))) #'user/fib user=> (time (fib 38)) "Elapsed time: 601.563589 msecs" 63245986 And this returns the error you specified: user=> (defn fac [n] (loop [n n r 1] (if (zero? n) 1 (recur (dec' n) (*' r n))))) java.lang.RuntimeException: java.lang.IllegalArgumentException: recur arg for primitive local: r is not matching primitive, had: java.lang.Number, needed: long (NO_SOURCE_FILE:13) Which is really poor behavior. Having numeric literals default to primitive types is great but this behavior does not match the documentation. To quote: "long-and-smaller integers promote in all cases, even when given integer primitives" with the prime ops. Any behavior other than that is confusing and essentially means the programmer cannot have dependable bindings (to be fair, boxing at the start of the loop fixes it but whatever). I fully acknowledge that the reason I don't understand 'primitive-by-default locals' may be because I'm so new at Clojure (and functional programming), so take this suggestion with a grain of salt: locals should default to the type specified in code (which means the prime ops should cause the rebind to auto-box/upgrade like the documentation dictates) or have sensible defaults (like literals default to primitives (which is awesome!)). At least that makes sense to me in a dynamic context. > Really? It seems tedious to me. Don't you get tired of saying int i = > 42 in Java, when you know full well the compiler knows 42 is an int? I > do, and Clojure is competing with languages that infer the right types > without the redundancy. Agree 100%, which is partly why this silly loop/recur behavior needs to be fixed. -- 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