[CLJ-701] Compiler loses 'loop's return type in some cases Created: 03/Jan/11 Updated: 12/Apr/13 |
|
| Status: | Open |
| Project: | Clojure |
| Component/s: | None |
| Affects Version/s: | Approved Backlog |
| Fix Version/s: | Release 1.6 |
| Type: | Defect | Priority: | Major |
| Reporter: | Chouser | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Environment: |
Clojure commit 9052ca1854b7b6202dba21fe2a45183a4534c501, version 1.3.0-master-SNAPSHOT |
||
| Approval: | Vetted |
| Description |
(set! *warn-on-reflection* true)
(fn [] (loop [b 0] (recur (loop [a 1] a))))
Generates the following warnings: recur arg for primitive local: b is not matching primitive, had: Object, needed: long Auto-boxing loop arg: b This is interesting for several reasons. For one, if the arg to recur is a let form, there is no warning: (fn [] (loop [b 0] (recur (let [a 1] a)))) Also, the compiler appears to understand the return type of loop forms just fine: (use '[clojure.contrib.repl-utils :only [expression-info]])
(expression-info '(loop [a 1] a))
;=> {:class long, :primitive? true}
The problem can of course be worked around using an explicit cast on the loop form: (fn [] (loop [b 0] (recur (long (loop [a 1] a)))))
Reported by leafw in IRC: http://clojure-log.n01se.net/date/2011-01-03.html#10:31 |
| Comments |
| Comment by a_strange_guy [ 03/Jan/11 4:36 PM ] |
|
The problem is that a 'loop form gets converted into an anonymous fn that gets called immediately, when the loop is in a expression context (eg. its return value is needed, but not as the return value of a method/fn). so (fn [] (loop [b 0] (recur (loop [a 1] a)))) gets converted into (fn [] (loop [b 0] (recur ((fn [] (loop [a 1] a)))))) see the code in the compiler: this conversion already bites you if you have mutable fields in a deftype and want to 'set! them in a loop |
| Comment by Christophe Grand [ 23/Nov/12 2:28 AM ] |
|
loops in expression context are lifted into fns because else Hotspot doesn't optimize them.
Adressing all those problems isn't easy. [1] beware of |