Rohde Fischer
09/21/2024, 10:54 AMMapWithDefault
interface design, in part exactly due to the things I'm bumping into here. I'm surprised by both the fact that it's private
- why would one want to prevent a 3rd party to make use of that interface? And secondly why the default value isn't a value on that interface. That could've allowed me to write a wrapper plusWithValue
or whatever, if it's not already there, and if it's there, there's probably all sorts of other utility functions that could make sense to allow 🙂ephemient
09/21/2024, 2:19 PMMapWithDefault
is only practically usable in situations like
val x by map.withDefault { fallback }
anything more than that would require more changes to the rest of the collections apiephemient
09/21/2024, 2:20 PMmapWithDefault["x"]
is still nullable, mapOf("a" to 1).withDefault { 2 } != mapOf("a" to 1, "b" to 2).withDefault { 2 }
, etc.Rohde Fischer
09/23/2024, 7:43 AMx
by a delegate in this situation?Rohde Fischer
09/23/2024, 7:56 AMplusWithValue
that behaves as desired. Otherwise the API practically enforces mutable maps on me in these situations, and then I'd have to start making all sorts of workarounds to not open the pure hell mutability can be, a simple example:
class ClassWithMaps {
private val _mapOfMaps = mutableMapOf<Key1, Map<Key2, Value>>().withDefault { emptyMap().withDefault { defaultValue } }
// Hide all mutability and avoiding the can of worms of values changing while the client does whatever with the map it read
val mapOfMaps: Map<Key1, Map<Key2, Value>>
get() = _mapOfMaps.toMap()
fun modifyMyMap() {
val key1 = someKey1()
val entry = someKey2ToValue()
val currentValue = _mapOfMaps.getValue(key1)
_mapOfMaps[key1] = currentValue + entry // This breaks the inner withDefault
}
}
with those exposed I could at least have some kind of extension for this task, or in this case where I know it would always be a MapWithDefault
do something like:
class ClassWithMaps {
// ..
fun modifyMyMap() {
// ..
val currentValue = _mapOfMaps.getValue(key1) as MapWithDefault
_mapOfMaps[key1] = (currentValue + entry).withDefault { currentValue.defaultValue }
}
}
a logic which I could further make more readable, by having an extension function or similar