Huib Donkers
05/31/2024, 9:13 AMpublic operator fun <T> Iterable<T>.minus(elements: Iterable<T>): List<T>
Is there a reason it's not defined as follows:
public operator fun <T> Iterable<T>.minus(elements: Iterable<*>): List<T>
(note the type of the argument elements
)
Consider the following code:
val a = listOf(1, 2) // inferred type: List<Int>
val b = listOf(1, "string") // inferred type: List<Any>
val c = a - b // inferred type: List<Any>
With the alternate definition the type of c
would always be equal to the type of a
, regardless of the type of b
. This would seem correct and useful to me.Javier
05/31/2024, 9:55 AMHuib Donkers
05/31/2024, 10:09 AMval a = listOf(1, 2) // inferred type: List<Int>
val b = listOf("string") // inferred type: List<String>
val c = a - b // inferred type: List<Any>
I would understand (and appreciate) an error or warning when the element type of a
is not a subtype of the element type of b
(in those cases, the only possible result would be an empty list, unless maybe when you're working with a odd kind of equals
...)
For the case where the element type of a
and b
are not equal, but elements of a
are a subtype of elements of b
I think it has its uses. But I would accept it if there was an compile time error.
I came across it in a situation a bit like this (playground)Klitos Kyriacou
05/31/2024, 10:12 AMcontains
is defined:
operator fun <T> Iterable<T>.contains(element: T): Boolean
By contrast, in Java the argument could be anything, as contains
takes Object
instead of `E`:
public interface Collection<E> extends Iterable<E> { ... boolean contains(Object o) ... }
So it seems that in Kotlin the intention was to require the arguments to be of the same type as the receiver, but the ability of the type parameter to be Any
is possibly unintended.Huib Donkers
05/31/2024, 10:32 AMcontains
uses the @kotlin.internal.OnlyInputTypes
annotation here:
public operator fun <@kotlin.internal.OnlyInputTypes T> Iterable<T>.contains(element: T): Boolean
.
So, maybe that annotation should have been added to minus
as well?Huib Donkers
05/31/2024, 10:35 AMcontains
would need to affect minus
though..ilya.gorbunov
06/02/2024, 12:14 PMminus
was introduced with the same parameters as plus
, but after some time, we thought about relaxing its signature in the way proposed in this thread.
However, now it may be not easy, considering various compatibility concerns and taking caution not to allow meaningless operations like List<String> - Int
Huib Donkers
06/03/2024, 10:43 AMlistOf("string") - 1
compiles and results in an inferred type of List<{Comparable<*> & java.io.Serializable}>
• "It needs to be backward compatible." But it seems to me that the only effect would be a more narrow/specific return type, which shouldn't break anything I would think...