Strange things: Kotlin complains that my function ...
# getting-started
w
Strange things: Kotlin complains that my function has a parameter that is never used. What am I supposed to do with this warning? My function must have it declared or it won't comply to the interface. The compiler should not add a noise with such a useless warning.
d
witoldsz: There is no interface here. The method is private...
Yes, it's used in a reference, but the compiler does not know that.
w
The compiler should not complain here, it should know what is is talking about or it should stay silent otherwise. It makes more harm than good in this case.
d
It does know what it's talking about. The parameter is unused.
w
But it should know that the
trace
is actually required there.
d
How? It's not required. You should probably use a lambda instead of a reference.
Just because it's required for the bind call does not mean that your method needs it.
a
or an anon object declaration to avoid the warning
w
No, I do not want to use lambda expression, it would make
init
a mess.
This is just a sample, real code has many more
bind
methods, entire file is made of that
init
and different event handlers.
d
you could make an extension method on the type that
eventQueue
returns that takes a lambda with just the one parameter and adapts it. If you make it inline you won't have any performance cost either for the additional indirection.
w
I would not like to tinker with MQ3 library adding complicated code just to make (buggy) compiler happy. Who is here for who? Compiler should help me write my code, not make my life harder.
d
I am not saying to add anything to the library...
I also think that this is most definitely not a bug.
w
Well yes, but still writing fragile code which would be actually useless (just to make warning go away).
d
Copy code
inline fun ThingThatEventQueueReturns.bind(name: String, handler: (String) -> Unit) = bind(name, { data, _ -> handler(data) })
Nothing fragile there. Code might not be 100% right, I can't test it obviously. But you get my point.
w
OK, so tell me: do you honestly believe it would make my code a better code, to make a workarounds just to make a useless warning go away?
d
It's not a workaround and it's not a useless warning 😛 So yes, I believe this is a valid solution.
w
It's hard for me to believe you are really for this warning in this case. It was designed to help me find bugs, to clean my code of useless arguments, not to "be creative" about making the warning go away.
d
The argument is useless. You do not use it in the method.
w
If what you say is true, I could remove this argument, but once I do it, the compiler throws a compilation error.
d
I honestly wonder how you want the compiler to figure this out. Say you have some method somewhere deep in a package, used all over the place. It has an unused argument. But somewhere, someone uses that method in a method reference with that parameter. Do you not want the compiler to tell you that the parameter is unused? That would concern me if it did that, because it's hiding a problem from you.
☝️ 1
I mean, if you were just calling this method, not using it in a reference, just removing the parameter would also result in a compile error, since the call sites now have an extra parameter. Do you want the compiler to omit the warning there, too? This all makes no sense to me.
w
So look at this from other angle: how can compiler NOT know it is required if once I remove it it instantly yields at me the code is invalid.
a
is this a compiler warning or an idea warning?
w
both complain
d
Copy code
fun foo(value: String) {
    // value stays unused
}

// somewhere else:
foo("hello")
If you remove "value" from the method, you get a compile error, since the method call is no longer valid.
Should the compiler not mark "value" as unused?
a
this is what i meant by using object, but sadly makes your code a couple lines longer 😞
w
This is not the same case, because you can remove the argument in both places. I cannot, because my function implements an interface (indirectly, but still) from a 3rd party lib.
a
val marketRequestedListener = object: Listener { override fun onMarketRequested(data: String, trace: Trace) { // your code here } }
d
You have to refactor the code using the method (
foo("hello")
in my example, the method reference in your example) in both cases.
In my case you have to remove the parameter, in your case you have to replace the reference with a lambda.
a
it wont complain about unused param cause is overriding
w
OK, everything you say make my code worse for no good reason. Compiler should figure it out the function is implementing (overriding) an interface.
d
No, it should not. Because the function is not implementing an interface.
w
Adding lines of code to make something obvious a thing more obvious to compiler.
It is implementing. This is how "this::" works here.
a
lambda like this: { data, trace -> onMarketRequested(data) }
so onMarketRequested no longer has an unused param
d
Yes, the function reference is the thing that's implementing. Not the function itself.
In the lambda case you would mark the 2nd parameter as "not needed" with
_
.
w
So, should I destroy the nice and easy to follow structure of a file (functions implementing event handlers) and make one huge
init
function with all the code inside lambdas? Or should I not use a super-nice feature of "this::" and just write by hand all the lambdas doing nothing but invoking the functions?
d
I would go with the references and write an adapter extension function if you want to omit the parameter.
Like I described above.
w
Can I be honest? This is crazy idea for me. I would treat this extra code as a garbage to make compiler's warning go away.
a
i guess you can always use supress warning and file an issue in youtrack
d
You already said that and I disagree. I think we should agree to disagree here, because I am going to go sleep now.
w
😄
It is getting late, we can agree on this 🙂
😄 1
supress warning
Looks like a kind of a compromise
I was hoping IDEA would suggest it and I forget about this.
Copy code
@Suppress("UNUSED_PARAMETER")
private fun onMarketRequested(data: String, trace: Trace) {…}
I hope one day Kotlin compiler will figure out the function as we see here is (indirectly) implementing an interface and such a workaround would not be necessary.
👍 1