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 firstbit? {:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )} [^long n] (== 1 (clojure.lang.Numbers/and n, 1))) (defn expint ^double [^double x, ^long c] (loop [result 1.0, factor x, c c] (if (> c 0) (recur (if (firstbit? c) (* result factor) result), (* factor factor), (bitshiftright c 1)) result)))
Last lines of the Java bytecode of `expint`:
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.replutils :only [expressioninfo]]) (expressioninfo '(loop [a 1] a)) ;=> {:class long, :primitive? true} (expressioninfo '(loop [a 1] (if true a (recur a))) ;=> nil
Patch attached.
Attachments
Activity
Christophe Grand
made changes 
Field  Original Value  New Value 

Description 
Reported here: https://groups.google.com/d/topic/clojure/atoFzbyuyos/discussion
(defn firstbit? {:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )} [^long n] (== 1 (clojure.lang.Numbers/and n, 1))) (defn expint ^double [^double x, ^long c] (loop [result 1.0, factor x, c c] (if (> c 0) (recur (if (firstbit? c) (* result factor) result), (* factor factor), (bitshiftright c 1)) result))) Last lines of the Java bytecode of `expint`: 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.replutils :only [expressioninfo]]) (expressioninfo '(loop [a 1] a)) ;=> {:class long, :primitive? true} (expressioninfo '(loop [a 1] (if true a (recur a))) ;=> nil Patch attached. 
Reported here: https://groups.google.com/d/topic/clojure/atoFzbyuyos/discussion
{noformat} (defn firstbit? {:inline (fn [n] `(== 1 (clojure.lang.Numbers/and ~n, 1)) )} [^long n] (== 1 (clojure.lang.Numbers/and n, 1))) (defn expint ^double [^double x, ^long c] (loop [result 1.0, factor x, c c] (if (> c 0) (recur (if (firstbit? c) (* result factor) result), (* factor factor), (bitshiftright c 1)) result))) {noformat} Last lines of the Java bytecode of `expint`: {noformat} 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; {noformat} The compiler doesn't currently infer the primitive type as soon as there is a recur: {noformat} (use '[clojure.contrib.replutils :only [expressioninfo]]) (expressioninfo '(loop [a 1] a)) ;=> {:class long, :primitive? true} (expressioninfo '(loop [a 1] (if true a (recur a))) ;=> nil {noformat} Patch attached. 
Stuart Halloway
made changes 
Approval  Screened [ 10004 ] 
Christophe Grand
made changes 
Assignee  Christophe Grand [ cgrand ] 
Rich Hickey
made changes 
Fix Version/s  Release 1.5 [ 10150 ]  
Approval  Screened [ 10004 ]  Ok [ 10007 ] 
Stuart Halloway
made changes 
Status  Open [ 1 ]  Closed [ 6 ] 
Resolution  Completed [ 1 ] 
Tests pass, code looks reasonable. Would appreciate additional review.