https://kotlinlang.org logo
#announcements
Title
# announcements
y

yawkat

11/16/2019, 10:22 AM
Why does += for MutableList behave differently from = with +? It's a bit weird and also against with liskov substitution because for List += works exactly like = with +
m

Marko Mitic

11/16/2019, 10:35 AM
What's the difference in behavour? No new list is created?
k

Kroppeb

11/16/2019, 10:43 AM
+=
doesn't work on
val list:List<T>
, but does work with
val mutableList:MutableList<T>
. It also works on
var list:List<T>
but IIRC on
var mutableList<T>
it doesn't work because it is ambiguous. AFAIK liskov substitution principle isn't violated.
b

Burkhard

11/16/2019, 1:10 PM
It still is a bit strange that
val mutableList += a
adds a, while
var mutableList = mutableList + a
creates a copy. It feels like
+
and
+=
do 2 different things (and they do). In this special case
+=
is not implemented as
a = a + b
whcih I think is what is meant by @yawkat. But as you pointed out
+=
is not vallid on mutable lists that are assigned to a
var
so this is not really a problem.
After looking up liskov’s substitution principle(https://en.wikipedia.org/wiki/Liskov_substitution_principle) I can confidently say it’s not violated here. Both
plus
and
plusAssign
are implemented as extension functions on
List
and
MutableList
so they are called statically. This means that substitution like in liskov’s case is not an issue.
y

yawkat

11/16/2019, 1:15 PM
liskov substitution also applies to static type changes
k

Kroppeb

11/16/2019, 1:15 PM
a += b
is always equivalent with
a = a+b
. but if both assignPlus and
plus
have been defined on a, there is ambiguity.
liskov would not apply here indeed cause they are extension functions.
you wan't liskov on a subtype so that if it is cast to a more general type, the contract of that type still applies
y

yawkat

11/16/2019, 1:16 PM
why? if i replace the static type of the variable with a subtype, the behavior changes
thats a liskov substitution violation imo
k

Kroppeb

11/16/2019, 1:20 PM
No, in this case it's 2 different functions that happen to have the same name. It's like saying this violates liskov cause
hi(String)
returns a
String
which doesn't extend
Pair<String,Any>
Copy code
fun hi(name:Any) = "hi" to name
fun hi(name:String) = "hi, $name!"
y

yawkat

11/16/2019, 1:34 PM
i know that, but this is an item in effective java
41 apparently. overloaded methods with similar types should always do the same thing
i always thought that was a part of liskov
k

Kroppeb

11/16/2019, 1:36 PM
no, liskov is about subtypes following the method contract of the supertype
👍 1
k

karelpeeters

11/16/2019, 5:48 PM
It's a bit unfortunate, yes. I can't imagine ever wanting
+=
to mean "create a new list with an extra element".
y

yawkat

11/16/2019, 8:14 PM
eh, that's the sane behavior, because thats exactly what + does
2 Views