[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: |
|
| 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. |