Fork me on GitHub
#clojure-dev
<
2015-11-30
>
ghadi21:11:16

bronsa: are you saying that because Long accepts long and String and get-in returns a box, that the compiler should prefer String?

ghadi21:11:42

I don't think that would be correct in the face of the casting

bronsa21:11:55

@ghadi: I'm pretty sure that's what the compiler already does tbh

bronsa21:11:25

.. sometimes apparently

ghadi21:11:28

i don't think so

bronsa21:11:37

it's inconsistent simple_smile

ghadi21:11:27

user=> (Long. (get-in {} [:a]))
Reflection warning, /private/var/folders/xn/64jx4gzn3f72t0n2t4r0w__40000gn/T/form-init7288158808655671254.clj:1:1 - call to java.lang.Long ctor can't be resolved.

bronsa22:11:07

give me 2 mins

bronsa22:11:56

[~]> cat test/*.java
package test;

public class Test1 {

    public Test1(long x) {}
    public Test1(Object x) {}

    public static void test(long x) {}
    public static void test(Object x) {}

}
package test;

public class Test2 {

    public Test2(long x) {}
    public Test2(String x) {}

    public static void test(long x) {}
    public static void test(String x) {}

}
[~]> clj
Clojure 1.8.0-master-SNAPSHOT
user=> (set! *warn-on-reflection* true)
true
user=> (fn [x] (test.Test1. x))
#<user$eval14$fn__15 user$eval14$fn__15@4d76f3f8>
user=> (fn [x] (test.Test1/test x))
#<user$eval18$fn__19 user$eval18$fn__19@1ed6993a>
user=> (fn [x] (test.Test2. x))
Reflection warning, NO_SOURCE_PATH:4:9 - call to test.Test2 ctor can't be resolved.
#<user$eval22$fn__23 user$eval22$fn__23@b1a58a3>
Reflection warning, NO_SOURCE_PATH:6:9 - call to static method test on test.Test2 can't be resolved (argument types: unknown).
#<user$eval28$fn__29 user$eval28$fn__29@4f2410ac>

bronsa22:11:41

@ghadi: I tried a bunch of times to rewrite the method matching logic to be consistent, but it's too broken. it's order-dependent and inconsistent, parts of clojure.core itself expect those inconsistencies

bronsa22:11:15

and w/o any documentation on how it should actually behave it's impossible to say what's intended behaviour or what's an accident/bug

bronsa22:11:21

there are even inconsistencies between having stuff type hinted as Object and not type hinted at all

cfleming22:11:10

@bronsa: @ghadi: For the Cursive type inference, I had to copy that logic from Clojure, I couldn’t get it to match otherwise.

ghadi22:11:22

Hmmm, the order dependent stuff is truly wtf

ghadi22:11:47

But really, arity collisions should reflect

cfleming22:11:40

@bronsa: What am I looking at in that snippet? Test1 does resolve because anything boxable can be assigned to Object, but in Test2 that’s not the case, right?

bronsa22:11:37

@cfleming: right, but we know that x will never be a primitive

bronsa22:11:53

so it's safe to say that the only available arity there would be the String one

cfleming22:11:05

True enough, we don’t know it’s a String though.

cfleming22:11:28

I’m not sure I disagree with Clojure there, it’s opting for more explicitness, basically.

bronsa22:11:16

sure, but then it's inconsistent w/ how it behaves when Object is involved. Object is no superclass to long

cfleming22:11:01

True, but since we know it’s not primitive, Object is a superclass of whatever the arg is, right?

ghadi22:11:35

cfleming: there is a difference in the order that they are declared

ghadi22:11:39

in the Java source

ghadi22:11:53

errrr, maybe not

ghadi22:11:09

Sigh, don't read stuff on your phone.

cfleming22:11:14

I’m wondering if I’m blind simple_smile

ghadi22:11:11

bronsa: primitive vs Box doesn't really matter right because of casting? Long is castable to long

bronsa22:11:46

yeah, I guess it might make sense in this case

cfleming22:11:47

@ghadi: But in that case, it would be ambiguous since both long and Object would match, although IIRC there are some special cases there around boxed values being cast to primitives.

ghadi23:11:12

I don't understand why (Test1. x) doesn't reflect