https://kotlinlang.org logo
#stdlib
Title
# stdlib
r

Rob Elliot

01/16/2023, 6:01 PM
Just noticed - there's no
List<T>.take(n: Int): List<T>
only
Iterable<T>.take(n: Int): List<T>
which constructs a new ArrayList and copies elements in. Wouldn't this be more efficient on a List, as it could just return a view?
Copy code
fun List<T>.take(n: Int): List<T> = subList(0, n)
(And of course the same for
drop
)
j

jw

01/16/2023, 6:05 PM
that would make it susceptible to changes in the backing list which i suspect would surprise people
☝️ 2
r

Rob Elliot

01/16/2023, 6:06 PM
I wish Kotlin had made the default implementation of Lists immutable
e

ephemient

01/16/2023, 11:06 PM
wouldn't help unless you forbid calling that function on mutable lists, which requires a different type hierarchy
r

Rob Elliot

01/17/2023, 9:55 AM
Yes, I was imagining an
ImmutableList<T> : List<T>
interface as a parallel to
MutableList
c

CLOVIS

01/17/2023, 10:59 AM
It's a times like these I wonder if having
.take
be an extension function was a good idea. If it were a regular interface method with default implementation, immutable list implementations could have overriden it to provide a subList-based implementation when it's safe
e

ephemient

01/17/2023, 11:54 AM
kotlin collections intentionally reuse java collections, so adding new member functions is not possible
kotlinx.immutable takes the approach of providing its own extension functions, which will be used if imported. although it only has
plus
and
minus
currently, no reason
take
etc. couldn't use the same pattern. does have the downside of being difficult to tell what is happening locally though
c

CLOVIS

01/17/2023, 12:05 PM
“which will be used if imported” ← except if you use polymorphism, which you likely do
i

ilya.gorbunov

01/17/2023, 7:15 PM
An additional consideration is that if
take
was implemented as
subList
(given that the
take
contract is respected, for example, by doing so only for immutable lists), it could lead to retaining more objects from garbage collection than necessary. Suppose you have a large list, but only temporary, and you want to take and store for a long period a list of only several first elements from it. If you use
take
for that, and
take
is implemented as a view, it would retain the entire large list in memory when only several elements of it are needed.
c

CLOVIS

01/17/2023, 7:17 PM
And, indeed, I've seen multiple people complaining here that
String.substring
retains the original string 🙄
j

jw

01/17/2023, 7:17 PM
They changed that in Java 7
i

ilya.gorbunov

01/17/2023, 7:17 PM
AFAIK
substring
no longer does that.
c

CLOVIS

01/17/2023, 7:18 PM
Really? Damn.
e

ephemient

01/18/2023, 6:08 AM
on a similar note, C++11 also ended up forbidding implementations from sharing backing buffers between strings, justified by https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2668.htm (although the situation there was a bit different due to mutable strings)
4 Views