<< Back to previous view

[CLJ-1111] Loops returning primtives are boxed even in return position Created: 21/Nov/12  Updated: 22/Dec/12  Resolved: 22/Dec/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4
Fix Version/s: Release 1.5

Type: Defect Priority: Major
Reporter: Christophe Grand Assignee: Christophe Grand
Resolution: Completed Votes: 3
Labels: None

Attachments: File prim-loop.diff    
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.



 Comments   
Comment by Stuart Halloway [ 25/Nov/12 7:12 PM ]

Tests pass, code looks reasonable. Would appreciate additional review.

Comment by Timothy Baldridge [ 26/Nov/12 10:59 AM ]

Tests also pass here. Looked through the code and played with a patched version of Clojure. I can't see a problem with it.

Comment by Christophe Grand [ 27/Nov/12 4:40 AM ]

FYI, gvec.clj has two loops which return primitives and thus was formerly boxed.

Generated at Sun Nov 23 23:30:37 CST 2014 using JIRA 4.4#649-r158309.