mg6maciej
04/23/2017, 7:40 PMpublic operator fun <T> Iterable<T>.minus(element: T): List<T>
be defined with element as nullable?
public operator fun <T> Iterable<T>.minus(element: T?): List<T>
I.e. if you call listOf<String>(...) - null as String?
it would just return the same List<String>
and not List<String?>
as it currently does.mg6maciej
04/24/2017, 11:51 AMminus
currently. It could even be changed to element: Any?
, but I'm not sure this would be very useful.snrostov
04/24/2017, 11:53 AMT
nullable itself?mg6maciej
04/24/2017, 11:53 AMmg6maciej
04/24/2017, 11:54 AMT
is subclass of T?
snrostov
04/24/2017, 11:54 AMlistOf(1, null, 2) - null
this would work?mg6maciej
04/24/2017, 11:57 AMlistOf(1, null, 2) - null as Int?
snrostov
04/24/2017, 12:04 PMprintln(listOf(1, null, 2) - null as Int?)
outputs: 1, 2
if you change operator to something like this:
public operator fun <T> Iterable<T>.minus(element: T?): List<T> {
if (element == null) {
return this.toList()
}
...
then
println(listOf(1, null, 2) - null as Int?)
output: 1, null, 2
or I'm missed something?mg6maciej
04/24/2017, 12:15 PMval list1: List<Int?> = arrayListOf(1, null).minusNullable(null)
println("list1: $list1")
val list2: List<Int> = arrayListOf(1, 2).minusNullable(null)
println("list2: $list2")
compiles and prints:
list1: [1]
list2: [1, 2]
where minusNullable
is a slightly changed minus
operator (essentially argument type changed to T?
):
fun <T> Iterable<T>.minusNullable(element: T?): List<T> {
val result = ArrayList<T>()
var removed = false
return this.filterTo(result) { if (!removed && it == element) { removed = true; false } else true }
}
mg6maciej
04/24/2017, 12:18 PMif (element == null) { return this.toList() }
is wrong. If it's null
, you still want to remove it if it exists in the list.mg6maciej
04/24/2017, 12:21 PMT?
is that it still returns List<T>
even if you pass something that is potentially null.snrostov
04/24/2017, 12:24 PMmg6maciej
04/24/2017, 12:25 PMT?
is supertype of T
(as well as Any
and Any?
are), no code existing currently would break.ilya.gorbunov
04/24/2017, 12:54 PMilya.gorbunov
04/24/2017, 12:55 PMmg6maciej
04/24/2017, 12:55 PMmg6maciej
04/24/2017, 12:57 PMT?
, but Any?
could possibly also be used instead.mg6maciej
04/24/2017, 12:57 PMmg6maciej
04/24/2017, 12:59 PMMutableCollection::remove
, just to Iterable::minus
(with element, as well as other arguments).mg6maciej
04/24/2017, 1:01 PMmg6maciej
04/24/2017, 1:55 PMopen class A
open class B : A()
class C : B()
fun usageTest() {
val list = mutableListOf<C>()
list.remove(null as Any?)
list.remove(Any())
list.remove(A())
list.remove(B())
list.remove(null as C?)
list.remove(C())
}
All compile.mg6maciej
04/24/2017, 1:57 PMmg6maciej
04/24/2017, 2:33 PMilya.gorbunov
04/24/2017, 3:18 PMIt's not only for direct supertype, unless direct means something else.Yeah, turns out I've actually meant something else 😆 I mean you shouldn't be able to minus a
String
from a List<Int>
even if you can minus Any
from that list. That's how MutableCollection.remove
extension works.
Although now you can, so it might be a source breaking change.ilya.gorbunov
04/24/2017, 3:20 PMSo I wanted to make this change in Kotlin's stdlib and see how it works, but I failed to run all tests. Is there a "tutorial" what needs to be done to run stdlib's test suite? I finished pretty early at setting JDK_16, 17 and 18.Yes, take a look at this readme: https://github.com/JetBrains/kotlin/tree/master/libraries If you have any problems with building and running tests, welcome to share them in #kontributors
mg6maciej
04/24/2017, 7:40 PMList<Any>
in that situation. That's a shame.