# Public review of the Standard Library APIs \[Closed\]

**URL:** <https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362>\
**Category:** Libraries\
**Created:** [December 17, 2015, 1:32pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362 "2015-12-17T13:32:41Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![voddan](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/voddan/32/1673_2.png) [@voddan](https://discuss.kotlinlang.org/u/voddan)\
**Post date:** [December 19, 2015, 1:11pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/21 "2015-12-19T13:11:23Z")

</div>

Kotlin (after Java) lacks functions for printing bytes as hexadecimals. The best there is is `Integer.toHexString(aByte.toInt())`. I think we need `Byte.toHexString()`, `Int.toHexString()`, `ByteArray.toHexString()`, and some others. Python has a nice set of such functions.

And maybe an `md5(ByteArray): ByteArray` would be nice too, since it is often used on its own (e.i. for salting)

---

<div class="post-metadata">

**Author:** ![CodeAnxiety](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/codeanxiety/32/1674_2.png) [@CodeAnxiety](https://discuss.kotlinlang.org/u/CodeAnxiety)\
**Post date:** [December 19, 2015, 11:33pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/22 "2015-12-19T23:33:00Z")

</div>

Sorry if someone already mentioned this.

Personal preference, but I think the `apply`, `run`, and `let` extensions should be infix functions.

```
val map = hashMapOf<String, String>().apply { 
    put("Key", Value")
}

```

Looks more confusing and out of place than this…

```
val map = hashMapOf<String, String>() apply {
    put("Key", Value")
}

```

… because the former looks like (to the uninitiated) a type specific extension (which it is), where the latter looks like a language idiom. Viewing it as a language idiom may more likely lead an interested user toward the language reference for guidance (which is the correct place) rather than the type. Assuming of course they aren’t using IDEA and can’t just ctrl+click `.apply`. 😄

Of course, like I said, this is just a personal preference, but changing it to an infix wouldn’t break any existing code and leave it up the user.

---

<div class="post-metadata">

**Author:** ![pniederw1](https://avatars.discourse-cdn.com/v4/letter/p/0ea827/32.png) [@pniederw1](https://discuss.kotlinlang.org/u/pniederw1)\
**Post date:** [December 20, 2015, 12:15am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/23 "2015-12-20T00:15:25Z")

</div>

> [@npryce](#):
>
> I would like the extension methods defined for collections and iterables to be made type safe by returning nullable types rather than throwing exceptions. For example, first() throws if there is no first element; it should instead return T?.

The current approach, namely to stay in line with Java collection APIs by throwing exceptions, and to provide `orNull` variants (e.g. `firstOrNull()`) where appropriate, makes sense to me. Are there particular methods for which you are missing an `orNull` variant?

---

<div class="post-metadata">

**Author:** ![pniederw1](https://avatars.discourse-cdn.com/v4/letter/p/0ea827/32.png) [@pniederw1](https://discuss.kotlinlang.org/u/pniederw1)\
**Post date:** [December 20, 2015, 12:18am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/24 "2015-12-20T00:18:21Z")

</div>

**Iterable.forEachIndexed** : The parameter list of (the action passed to) `forEachIndexed` should naturally extend the parameter list of `forEach`. Because it’s `forEachIndexed` rather than `indexedForEach`, it should be `forEachIndexed { elem, idx -> ... }` rather than `forEachIndexed { idx, elem -> ... }`. The current order is counter-intuitive.

Same for other similar methods (e.g. `mapIndexed`).

---

<div class="post-metadata">

**Author:** ![andrewoma](https://avatars.discourse-cdn.com/v4/letter/a/c37758/32.png) [@andrewoma](https://discuss.kotlinlang.org/u/andrewoma)\
**Post date:** [December 20, 2015, 2:26am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/25 "2015-12-20T02:26:45Z")

</div>

In general, I’m a happy user of the standard library and haven’t encountered any recent gotchas that I recall.

I’ve just had a quick read through the sources and here’s what stood out.

Edit: remove X from the links to follow  
**Overloaded methods accepting a string Charset**

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/collections/ArraysJVM.kt#L68

Seems unnecessary for the rare occasions you’d use it and then Charset.forName() is available.

**Usage of raw time units**

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/concurrent/Timer.kt#L12

Not a big deal, but some kind of units would be better (although I understand you’re targeting 1.6).

**Inconsistent naming of block-like structures (block, body, operation, action)**

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/concurrent/Thread.kt#L25

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/io/FileReadWrite.kt#L178

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/util/Integers.kt#L10

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/io/ReadWrite.kt#L25

I’d prefer a consistent name where possible.

**Leaking of internals**

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/io/Constants.kt#L9

**Amusing Australian slang**

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt#L82

“Is rooted” is pretty much equivalent to “is f\*cked” in Australia. I’m Australian and would like to keep it regardless. 😉

**Same functionality via different methods**

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/generated/\_Collections.kt#L153

I think there’s other cases of this too. I’d strongly prefer one way of doing things for readability.

**References to java.util**

Xhttps://github.com/JetBrains/kotlin/blob/01095bc65257f399a97768e1f0f9ae7d31144a23/libraries/stdlib/src/generated/\_Collections.kt#L1048

I’m a bit uneasy about stdlib things returning anything from java.util. It seems prudent to only return kotlin.\* interfaces to allow other backends not to be tainted by java packages. There’s many cases of this e.g. `arrayListOf()`

**Evolution**  
In general I think you should feel free to evolve the standard library after 1.0 as long as you maintain backwards compatibility. Even dropping things should be fine as you have the `Deprecated.HIDDEN` mechanism.

**Documentation**  
Some overview docs are sorely needed for the `Ordering` functions and how they are chained together. Likewise for `Ranges` and `Regexes`. As far as I can tell its all perfectly functional, but it’s not obvious how to use them.

Cheers,  
Andrew

---

<div class="post-metadata">

**Author:** ![pniederw1](https://avatars.discourse-cdn.com/v4/letter/p/0ea827/32.png) [@pniederw1](https://discuss.kotlinlang.org/u/pniederw1)\
**Post date:** [December 20, 2015, 9:33am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/26 "2015-12-20T09:33:59Z")

</div>

**FileTreeWalk** : Often I don’t want to include the `start` directory itself in the walk, but there appears to be no clean way to achieve this. The constructor’s `filter` parameter excludes directories recursively, and filtering the returned `Sequence` has no effect on `enter` and `leave`.

KDoc neither mentions that `start` itself is included in the walk, nor that the filter passed to the constructor filters directories recursively (this is only mentioned for the `treeFilter` method). The `filter` parameter should be renamed to `treeFilter`, to match the corresponding method name like the other parameters do.

**Update** : The fact that a `FileTreeWalk` sequence can only be iterated a single time, and will be empty from then on (because `iterator` returns the same iterator each time), came as a big surprise to me. If this is intended, it needs to be documented. If multiple iterations aren’t supported, I’d expect subsequent iterations to fail.

---

<div class="post-metadata">

**Author:** ![pniederw1](https://avatars.discourse-cdn.com/v4/letter/p/0ea827/32.png) [@pniederw1](https://discuss.kotlinlang.org/u/pniederw1)\
**Post date:** [December 20, 2015, 11:31pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/29 "2015-12-20T23:31:03Z")

</div>

**T.apply** : When I read `apply`, I think of function application. `configure` would be a better name, and would convey that this method is all about side effects.

---

<div class="post-metadata">

**Author:** ![pniederw1](https://avatars.discourse-cdn.com/v4/letter/p/0ea827/32.png) [@pniederw1](https://discuss.kotlinlang.org/u/pniederw1)\
**Post date:** [December 21, 2015, 7:29am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/30 "2015-12-21T07:29:39Z")

</div>

**Arrays** : Kotlin doesn’t seem to provide a way to compare array contents, leaving `java.util.Arrays.(deep)Equals` as the only option. Also, there is no `assertArrayEquals`.

Any chance for `equals` to compare deep array contents? Would be sad if Java’s mistake had to be repeated. Same for `toString`.

PS: I couldn’t find any docs whatsoever on how Kotlin compares arrays.

---

<div class="post-metadata">

**Author:** ![daelyasy](https://avatars.discourse-cdn.com/v4/letter/d/22d042/32.png) [@daelyasy](https://discuss.kotlinlang.org/u/daelyasy)\
**Post date:** [December 21, 2015, 7:48am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/31 "2015-12-21T07:48:53Z")

</div>

I think that it is a pity that Kotlin standard library and syntax does not have better support for half open ranges (i,e start\<= i \< end), since they are so common, considering also they exist in many other languages (Swift, Ruby, Python, Go (slices)), But I guess this is something that can added post 1.0. The standard library has only ClosedRange, so I guess that introduction of OpenRange is s planned for the future

---

<div class="post-metadata">

**Author:** ![mikehearn](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mikehearn/32/1424_2.png) [@mikehearn](https://discuss.kotlinlang.org/u/mikehearn)\
**Post date:** [December 21, 2015, 9:31am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/32 "2015-12-21T09:31:37Z")

</div>

It compares arrays in an identical way to Java (by reference). I’ve gone around this one before and tried to convince Andrey to change it, but IIRC there were some complicated edge cases and the straightforward “== means the .equals method” consistency won, even though it’s a technical rather than semantic consistency. It’s regrettable for sure because “a == b” with two arrays basically never does what you expect.

If we had value types it could be patched over. I have an OpaqueBytes class in my code that fixes equals/hashcode/tostring for byte arrays but it’s obviously an inferior solution.

---

<div class="post-metadata">

**Author:** ![voddan](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/voddan/32/1673_2.png) [@voddan](https://discuss.kotlinlang.org/u/voddan)\
**Post date:** [December 21, 2015, 10:25am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/33 "2015-12-21T10:25:18Z")

</div>

The `lazy` function’s signature `fun <T> lazy(initializer: () -> T): Lazy<T>` does not allow to use the instance reference while defining an extension property. See the problem here: [this reference in a lazy initializer of kotlin extension property - Stack Overflow](http://stackoverflow.com/questions/34391255/this-reference-in-a-lazy-initializer-of-kotlin-extension-property/34393382#34393382)

I suggest changing the implementation to save `this` reference and pass it to the initializing body: `fun <T> lazy(initializer: T.() -> T): Lazy<T>`

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [December 21, 2015, 7:11pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/34 "2015-12-21T19:11:15Z")

</div>

> [@mikehearn](#):
>
> Another thought: some stuff should be moved into kotlin.text seeing as classes are on the move:
> 
> Typography  
> CharCategory  
> CharDirectionality  
> Charsets
> 
> Possibly also the extension properties and functions for Char\* stuff and String extensions.

> [@medium](#):
>
> In my opinion there too much functions in the kotlin package. I would prefer some grouping (e. g. collections related functions, string related functions and so on).

Classes are going to be moved in RC, and functions are moved in beta4. There will be 4 packages where functions and classes would land in: `kotlin.collections`, `kotlin.ranges`, `kotlin.sequences` and `kotlin.text`.

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [December 22, 2015, 3:39pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/35 "2015-12-22T15:39:35Z")

</div>

> [@pniederw1](#):
>
> Extension method File.inputStream should have return type FileInputStream rather than InputStream.
> 
> Extension method File.outputStream should have return type FileOutputStream rather than OutputStream.

Agree, these methods may return more specific type.

> [@pniederw1](#):
>
> FileTreeWalk: Often I don’t want to include the start directory itself in the walk, but there appears to be no clean way to achieve this. The constructor’s filter parameter excludes directories recursively, and filtering the returned Sequence has no effect on enter and leave.
> 
> Update: The fact that a FileTreeWalk sequence can only be iterated a single time, and will be empty from then on (because iterator returns the same iterator each time), came as a big surprise to me. If this is intended, it needs to be documented. If multiple iterations aren’t supported, I’d expect subsequent iterations to fail.

Most of these issues are already fixed in beta4. We’re going to make `FileTreeWalk` constructor internal, so that the construction would be performed only with fluent methods. `treeFilter` is to be removed entirely, and recursive directory filtering is performed in `onEnter` callback.

Single time iterability is also fixed in beta4, now each iterator of `FileTreeWalk` sequence has its own independent state.

To exclude starting directory you can filter it out with `filter` or `filterNot` sequence operations.

---

<div class="post-metadata">

**Author:** ![koesie10](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/koesie10/32/1659_2.png) [@koesie10](https://discuss.kotlinlang.org/u/koesie10)\
**Post date:** [December 22, 2015, 10:20pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/36 "2015-12-22T22:20:52Z")

</div>

Could binary operations be added on all types to which they apply? Right now I often do:

```auto
val x: Byte = 1.toByte()
val y = x.toInt() and 1

```

---

<div class="post-metadata">

**Author:** ![pniederw1](https://avatars.discourse-cdn.com/v4/letter/p/0ea827/32.png) [@pniederw1](https://discuss.kotlinlang.org/u/pniederw1)\
**Post date:** [December 23, 2015, 5:59pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/37 "2015-12-23T17:59:39Z")

</div>

**Closeable.use** : I’m missing `AutoCloseable.use` for JDK 1.7+.

---

<div class="post-metadata">

**Author:** ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)\
**Post date:** [December 25, 2015, 11:42am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/38 "2015-12-25T11:42:59Z")

</div>

Update: We are planning to close this call on Jan 11, 2016

---

<div class="post-metadata">

**Author:** ![mikehearn](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mikehearn/32/1424_2.png) [@mikehearn](https://discuss.kotlinlang.org/u/mikehearn)\
**Post date:** [December 27, 2015, 2:21am UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/41 "2015-12-27T02:21:46Z")

</div>

The “Any.to” extension method is perhaps not something that would be great to support forever. Although it’s nice to have in mapOf other times it’s just sort of junk hanging around.

---

<div class="post-metadata">

**Author:** ![kirill\_rakhman](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/kirill_rakhman/32/1692_2.png) [@kirill\_rakhman](https://discuss.kotlinlang.org/u/kirill_rakhman)\
**Post date:** [December 28, 2015, 7:44pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/42 "2015-12-28T19:44:34Z")

</div>

The stdlib is missing methods to instantiate `MutableList`, `MutableMap` and `MutableSet`. This is especially problematic since the new overload resolution algorithm doesn’t allow calling the `forEach` extension function on an `ArrayList` instance. I also created [https://youtrack.jetbrains.com/issue/KT-10531](https://youtrack.jetbrains.com/issue/KT-10531) to track this.

---

<div class="post-metadata">

**Author:** ![mplatvoet](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mplatvoet/32/7121_2.png) [@mplatvoet](https://discuss.kotlinlang.org/u/mplatvoet)\
**Post date:** [December 28, 2015, 8:06pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/43 "2015-12-28T20:06:20Z")

</div>

#consistent collection operations  
As raised in the Slack standard library channel I have some issues with the somewhat inconsistent behaviour between collection functions like `map`, `filter`, etc…

All functions related to `Iterable`s are returning snapshots where all functions related to `Sequence`s are lazily evaluated. This makes it very hard to reason about what code is doing. Take for instance the following example code:

```auto
fun main(args: Array<String>) {
    val xs = listOf(1,2,3)
    val mapped = xs.map(plusOne)
    
    mapped.forEach { }
    mapped.forEach { }
}

val plusOne : (Int) -> Int = {i -> println("mapping [$i]"); i + 1}

```

By merely changing `listOf(1,2,3)` to `listOf(1,2,3).asSequence()` the behaviour changes from mapping once to mapping per call/iteration.

##proposition  
So I prefer all standard library collection functions to be lazily evaluated so everything becomes consistent and therefor easier to reason about. If you do require a snapshot a simple library function can be introduced like `Iterable/Sequence.toList()`.

##disadvantages

- changes behaviour of current code bases without the possibility to properly emit (compiler) warnings
- lazy evals can be prone to errors to inexperienced developers, implicitly making db calls or keeping large amounts of memory alive in closures.

##advantage

- consistent API
- if there is any change to this, now is the time, can’t be done later

##other remarks  
As pointed out by @natpryce in the Slack channel it’s not that clear anymore why there should be an Iterable and a Sequence. I thought there was some sound reason for this but I have already forgotten.

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [December 30, 2015, 5:24pm UTC](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362/44 "2015-12-30T17:24:20Z")

</div>

Just looked at with and agree it seems totally worthless. Sure seems like it should be an extension function instead of passing receiver as a parameter. In reality it is like map function. As an extension function it could be renamed apply and it is simply apply that returns a new value or possibly called transform.

let is just like run but instead of an extension function it takes a function that accepts the target as first parameter. So it seems to me it should also just be called run.

But in reality all of these methods (if with were also an extension function) could have the same name. The only difference being what type of function is passed, but that would probably cause ambiguity with lambdas.

[Previous page](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362.md?page=1)

[Next page](https://discuss.kotlinlang.org/t/public-review-of-the-standard-library-apis-closed/1362.md?page=3)
