Uploaded image for project: 'Clojure'
  1. CLJ-1111

Loops returning primtives are boxed even in return position

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Completed
    • Affects versions: Release 1.4
    • Fix versions: Release 1.5
    • Labels:
      None
    • Approval:
      Ok
    • Patch:
      Code

      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.

        Attachments

          Activity

            People

            • Assignee:
              cgrand Christophe Grand
              Reporter:
              cgrand Christophe Grand
            • Votes:
              2 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: