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

Reply via email to