https://kotlinlang.org logo
Title
m

Mark

06/02/2022, 2:42 PM
I’m curious regarding the naming conventions behind having
toList()
but then
asSequence()
instead of
toSequence()
?
j

Joffrey

06/02/2022, 2:43 PM
Usually in the Kotlin stdlib
asSomething()
implies that the returned
Something
wraps the receiver (or exposes it as a different type), while
toSomething()
implies that the new
Something
will copy everything it needs from the receiver and have no further relation to it.
:thank-you: 2
m

Mark

06/02/2022, 2:46 PM
Although in this particular case an iterator on the
asSequence()
vs
toList()
will return the same items. But I suppose it wouldn’t be expected to do a deep copy, so that’s a moot point
j

Joffrey

06/02/2022, 2:47 PM
The difference is that
toList()
will create a new list from the existing one, while
asSequence()
will only bridge the type but still take its items from the original collection. If you were to change the original collection after conversion, the
toList()
variant will not be affected while the
asSequence()
result will show the changes: https://pl.kotl.in/mT9gSB1Uc
👍 2
m

Mark

06/02/2022, 2:51 PM
I find it a bit confusing regarding
toCollection(destination)
which kind of uses a very different interpretation of
to
. I suppose it maintains the philosophy of
to
being unaffected by changes to the original
j

Joffrey

06/02/2022, 2:53 PM
It's similar. The items will be inserted into a new independent collection, just like
toList
. The only difference is that you provide the new collection yourself instead of letting the function create it. But I agree the collection will not necessarily be "new' in that case. I find the
as-
prefix pretty neat because it aligns with the casting operator
as
, which is really hinting towards the fact that we express the object as a different type, but it's really the same object behind the scenes.
👍 3
e

ephemient

06/02/2022, 3:35 PM
yep, the naming convention carries over to the rest of stdlib, although the difference isn't really observable for immutable types, and there aren't many built-in mutable types
👍 1
val a = mutableListOf("hello", "world")
val b = a.asReversed()
assert(b == listOf("world", "hello"))
a[0] = "goodbye"
assert(b == listOf("world", "goodbye"))

val c = listOf(1)
val d = c.toIntArray()
assert(d[0] == 1)
c[0] = 2
assert(d[0] == 1)
n

nkiesel

06/02/2022, 8:16 PM
(that should be a
val c = mutableListOf(1)
)
m

Mark

06/06/2022, 1:24 PM
On a related note, I guess an implementation like this is bad practice?
fun CharSequence.asSpannableStringBuilder() =
    this as? SpannableStringBuilder ?: SpannableStringBuilder(this)
and that we should prefer:
fun CharSequence.toSpannableStringBuilder() = SpannableStringBuilder(this)
Either way, you shouldn’t use the original receiver because it contains spans that are now used by the returned object because spans are not allowed to be used in multiple builders.
e

ephemient

06/06/2022, 1:29 PM
spans should either be copyable between spannables or implement NoCopySpan, so that shouldn't be an issue. the problem with your first function is that it's unclear whether the original receiver will be mutated or not.
m

Mark

06/06/2022, 1:29 PM
Oh interesting, I didn’t know about
NoCopySpan
e

ephemient

06/06/2022, 1:30 PM
this is rather android-specific, but you should consider using or following the precedent of https://developer.android.com/reference/kotlin/androidx/core/text/package-summary#buildSpannedString(kotlin.Function1)
m

Mark

06/06/2022, 1:34 PM
Hmm, I normally use that, but good to see how it returns
SpannedString(builder)
rather than the
SpannableStringBuilder
itself, for example as a
CharSequence
On another Android-specific (and non-Kotlin!) note I see that
SpannedString
does:
public static SpannedString valueOf(CharSequence source) {
        if (source instanceof SpannedString) {
            return (SpannedString) source;
        } else {
            return new SpannedString(source);
        }
    }
e

ephemient

06/06/2022, 1:36 PM
SpannedString
is immutable so that's fine
👍 1
m

Mark

06/06/2022, 1:41 PM
So yet another reason why
SpannedString
is a better return type than
CharSequence