Functions reference question


#1

Can somebody tell me what's wrong with this code? I can't understand why it's failing :)

 
public class Test {
   fun outer() {
      val f:(Int)->Int = ::f1
   }
   
   fun f1(x:Int) = 0
}

The compiler is telling me that `::f1` is `kotlin.reflect.KMemberFunction1<Test, kotlin.Int, kotlin.Int>`. I don't see a reference to that `KMemberFunction1` anywhere in the code, nor in the docs. I guess I can change `f` to be that, but it looks uglier and I still don't understand why my code doesn't work :).


#2

If you're using M12, this is indeed KMemberFunction1 which takes two parameters: a Test instance and an Int, so the full type is "KMemberFunction1<Test, Int, Int>" which extends from "Test.(Int) -> Int", which you can specify as f's type.

In current builds this is changed and “::f1” is type-checked to “KFunction2<Test, Int, Int>” which extends from “(Test, Int) -> Int”.

Most probably you were meaning to use a function which has a Test instance bound to it, this is now impossible but will be supported in the future.


#3

Thank you. Yeah, I wanted to have a function with an instance boud to it (so, a reference to an instance method, basically).

Let’s say I change it to KMemberFunction1 or KFunction2 (I’m upgrading my project right now to 0.12.1218, didn’t know you guys released a new one). How I can do this now?

public class Test {
   fun test1() {
      val t: KMemberFunction1<Test, Number, Int> = ::t2
   }

  fun t2(x:Int) = 0
}

`Int` on my parameter is not accepted as a Number, obviously. I've tried with `out Number`, but that doesn't compile either. Is there a way of making this work?

Thanks :slight_smile:


#4

This won't work: t2 takes an Int as a parameter, not a Number, and the type checker tells you that with the "type mismatch" error. You can't make a function which only works with ints magically work with any numbers.

(Note that 0.12.1218 is in fact still M12 with bug fixes.)


#5

I see. Also, I might not have understood you the first time. Even if I got that to work somehow, KMemberFunction1 still needs an instance of the class when calling `invoke` (which I don't have) so that won't work either...

Thank you anyway, I’ll try to find another solution for now.


#6

I've updated my code to use 1.0-SNAPSHOT (build 20150727.132610-383 right now) but `::f1` type is still `KMemberFunction1<>` (although casting it to KFunction2 works fine). Should this work, or you were referring to some other builds?


#7

There's no such type as KMemberFunction or KMemberFunction1 anymore in snapshot builds, please check if you've updated both the plugin and the runtime.


#8

I haven't updated the IDEA plugin, if that's the one you mean. I've updated my kotlin-reflect, kotlin-runtime and kotlin-stdlib libraries. I'll try updating the IDEA plugin (is it on Maven as well, or should I use M12/0.12.1218.Idea142.4-142.3371.3 from GitHub?)


#9

Ok, so my problem seems to be that the outdated IDEA plugin is compiling on its own (I was being stupid, totally forgot about that) instead of using the Maven plugin. Using the Maven plugin works perfectly (although IDEA shows errors, of course), thanks :)