Thread
#stdlib
    gregorbg

    gregorbg

    3 years ago
    Just wondering, what is the rationale for the
    get
    operator returning
    Nullable?
    types for Maps but not for Lists? I understand that in a map, you may not know whether the key is set. But in a List, you may not know whether the index exists (i.e. the list is long enough) either??!
    Shawn

    Shawn

    3 years ago
    I mean it’s pretty easy to check if
    index < list.size
    , but I suppose a better explanation is that maps or, more broadly, associative arrays allow for arbitrary mappings of keys to values, with no imposed relation between the keys, except for maybe data type (which you can get around with just a
    Map<Any, Value>
    )
    idiomatically speaking it makes more sense to return
    null
    if a key isn’t found because there isn’t necessarily a structural constraint that lets you easily and inexpensively tell if a key should be there
    whereas if a list has 5 elements in it and I ask for element 6, that’s clearly an out of bounds error
    also, a lot of the time with a Map, there’s usually a clean way to branch execution based on whether or not a key is there
    sure, sometimes you’re expecting a value and can’t proceed if it isn’t there, but other times you might just insert a new mapping or otherwise populate the map using that key
    Maps are used idiomatically in cases where you might be composing a set of relations between objects and it’s perfectly valid to return null if there is no relation yet
    gregorbg

    gregorbg

    3 years ago
    That last argument about purposefully wanting to return null is a very valid point that I did not consider before! 😄
    However, it still feels wrong or "brutal" to access values by
    getValue(key)
    even within a
    if (key in myMap.keys)
    branch
    Shawn

    Shawn

    3 years ago
    in many cases,
    getValue()
    can be avoided by just using the null-safety navigator and composing the operations you need to perform by way of
    ?.let { ... }
    ,
    takeIf { ... }
    , etc
    but yeah, I get where you’re coming from there
    karelpeeters

    karelpeeters

    3 years ago
    It also matches the Java behaviour 😒imple_smile:
    gregorbg

    gregorbg

    3 years ago
    True, but not a very strong argument on its own 😕
    Czar

    Czar

    3 years ago
    Yup, and it is not on its own, it goes hand in hand with Kotlin-Java interop and Kotlin's definition of pragmatism. Since Kotlin collections are mere wrappers/bunch of extensions on existing Java collections, it makes sense not to change behaviour.