Clojure

Type-hinting a var with primitive array pseudo-class results in IllegalArgumentException when the var is used as an arg

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Declined
  • Affects Version/s: Release 1.3
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

Example:

user=> (def ^longs la (long-array 0))
#'user/la
user=> (defn foo [] (alength la))
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: clojure.core$longs@32dfcb47, compiling:(NO_SOURCE_PATH:9) 

Workaround: use the class string, e.g., ^"[J"

Activity

Hide
Stuart Sierra added a comment -

Correct, this is not a bug. The reader will attempt to resolve symbols in the ^tag metadata form, so that it can resolve unqualified class names.

Show
Stuart Sierra added a comment - Correct, this is not a bug. The reader will attempt to resolve symbols in the ^tag metadata form, so that it can resolve unqualified class names.
Hide
Ben Smith-Mannschott added a comment - - edited

OK, I see the problem here: longs plays two roles in Clojure:

  1. As an unqualified symbol, it's taken to mean long[].class.
  2. clojure.core/longs is a definline function which calls clojure.lang.Numbers.longs(...).

The example in the issue description is expecting the first interpretation, but what we're actually getting is the second interpretation, i.e. the :tag is not a symbol longs, but rather a function (an instance of the class clojure.core$longs, to be precise).

So, it's as if we'd written this:

(def ^{:tag clojure.core/longs} la (long-array 0))

When really, we meant this:

(def ^{:tag 'longs} la (long-array 0))

While the behavior described by this issue is confusing, it looks to me like it's not a bug.

Show
Ben Smith-Mannschott added a comment - - edited OK, I see the problem here: longs plays two roles in Clojure:
  1. As an unqualified symbol, it's taken to mean long[].class.
  2. clojure.core/longs is a definline function which calls clojure.lang.Numbers.longs(...).
The example in the issue description is expecting the first interpretation, but what we're actually getting is the second interpretation, i.e. the :tag is not a symbol longs, but rather a function (an instance of the class clojure.core$longs, to be precise). So, it's as if we'd written this:
(def ^{:tag clojure.core/longs} la (long-array 0))
When really, we meant this:
(def ^{:tag 'longs} la (long-array 0))
While the behavior described by this issue is confusing, it looks to me like it's not a bug.
Hide
Ben Smith-Mannschott added a comment -

CLJ-851-test.patch

Provides a test to reproduce this issue, as well as a test that shows that the workaround of using ^"[J" as type hint works correctly.

Show
Ben Smith-Mannschott added a comment - CLJ-851-test.patch Provides a test to reproduce this issue, as well as a test that shows that the workaround of using ^"[J" as type hint works correctly.

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: