Clojure

External type hint inconsistency between regular functions and primitive functions

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Duplicate
  • Affects Version/s: Release 1.6
  • Fix Version/s: None
  • Component/s: None
  • Patch:
    Code
  • Approval:
    Triaged

Description

Consider the following example.

(set! *warn-on-reflection* true)

(defn f [n] (java.util.ArrayList. (int n)))

(let [al ^java.util.ArrayList (f 10)]
  (.add al 23))

As expected this does not warn about reflection. The following example shows the same scenario for a primitive function.

(set! *warn-on-reflection* true)

(defn g [^long n] (java.util.ArrayList. n))

(let [al ^java.util.ArrayList (g 10)]
  (.add al 23))
; Reflection warning, NO_SOURCE_PATH:2:3 - call to method add on java.lang.Object can't be resolved (no such method).

So the behavior of external type hints is inconsistent for regular functions and primitive functions.
Most likely, the external type hint information is somehow ignored for primitive functions since the case where they return no primitive value is not treated separately.

Activity

Hide
Nicola Mometto added a comment -

The following patch preserves the original metadata of the invoke form on the transformed .invokePrim expression

Show
Nicola Mometto added a comment - The following patch preserves the original metadata of the invoke form on the transformed .invokePrim expression
Hide
Alex Miller added a comment -

Not challenging the premise at all but workaround:

(let [^java.util.ArrayList al (g 10)]
  (.add al 23))
Show
Alex Miller added a comment - Not challenging the premise at all but workaround:
(let [^java.util.ArrayList al (g 10)]
  (.add al 23))
Hide
Gunnar Völkel added a comment - - edited

Well, the example above was already changed such that you can also place the type hint on the binding to check whether that works.
The actual problem arose when using the return value of the function exactly once without an additional binding.

Show
Gunnar Völkel added a comment - - edited Well, the example above was already changed such that you can also place the type hint on the binding to check whether that works. The actual problem arose when using the return value of the function exactly once without an additional binding.
Hide
Jozef Wagner added a comment -

Responding to Alex's comment, is there a consensus on which variant is (more) idiomatic? IMHO latter variant seems to be more reliable (as this issue shows, and for primitive hits too), and is consistent with 'place hint on a symbol' idiom which is applied when type hinting vars or fn args.

(let [symbol ^typehint expr] body)
(let [^typehint symbol expr] body)
Show
Jozef Wagner added a comment - Responding to Alex's comment, is there a consensus on which variant is (more) idiomatic? IMHO latter variant seems to be more reliable (as this issue shows, and for primitive hits too), and is consistent with 'place hint on a symbol' idiom which is applied when type hinting vars or fn args.
(let [symbol ^typehint expr] body)
(let [^typehint symbol expr] body)
Hide
Alex Miller added a comment -

They have different meanings. Generally the latter covers some cases that the former does not so it's probably the better one. I believe one of the cases is that if expr is a macro, the typehint is lost in the former.

Show
Alex Miller added a comment - They have different meanings. Generally the latter covers some cases that the former does not so it's probably the better one. I believe one of the cases is that if expr is a macro, the typehint is lost in the former.
Hide
Nicola Mometto added a comment -

The patch for http://dev.clojure.org/jira/browse/CLJ-1533?jwupdated=61127&focusedCommentId=35814 fixes this issue and more and should be preferred over this

Show
Nicola Mometto added a comment - The patch for http://dev.clojure.org/jira/browse/CLJ-1533?jwupdated=61127&focusedCommentId=35814 fixes this issue and more and should be preferred over this
Hide
Alex Miller added a comment -

Dupe of CLJ-1533

Show
Alex Miller added a comment - Dupe of CLJ-1533

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: