Details
-
Type:
Defect
-
Status:
Closed
-
Priority:
Major
-
Resolution: Completed
-
Affects Version/s: Release 1.4
-
Fix Version/s: Release 1.5
-
Component/s: None
-
Labels:None
-
Patch:Code
-
Approval:Ok
Description
Reported here: https://groups.google.com/d/topic/clojure/atoFzbyuyos/discussion
(defn first-bit?
{:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )}
[^long n]
(== 1 (clojure.lang.Numbers/and n, 1)))
(defn exp-int
^double [^double x, ^long c]
(loop [result 1.0, factor x, c c]
(if (> c 0)
(recur
(if (first-bit? c)
(* result factor)
result),
(* factor factor),
(bit-shift-right c 1))
result)))
Last lines of the Java bytecode of `exp-int`:
59 dload 5; /* result */ 61 invokestatic 40; /* java.lang.Double java.lang.Double.valueOf(double c) */ 64 checkcast 85; /* java.lang.Number */ 67 invokevirtual 89; /* double doubleValue() */ 70 dreturn;
The compiler doesn't currently infer the primitive type as soon as there is a recur:
(use '[clojure.contrib.repl-utils :only [expression-info]])
(expression-info '(loop [a 1] a))
;=> {:class long, :primitive? true}
(expression-info '(loop [a 1] (if true a (recur a)))
;=> nil
Patch attached.
Tests pass, code looks reasonable. Would appreciate additional review.