Ray Rahke
02/23/2024, 6:01 PMval x: MutableSet = mutableSetOf()
instead of
val x: MutableSet = MutableSet()
?Jeff Lockhart
02/23/2024, 6:06 PMMutableSet
is an interface, so it can't be constructed directly. mutableSetOf()
is a top-level function for constructing a MutableSet
implementation with passed in values, which returns an empty set when no values are passed.Joffrey
02/23/2024, 6:08 PMMutableSet()
to look like a constructor. I don't know why it wasn't. Maybe to avoid confusion like this, maybe because of the vararg.Jeff Lockhart
02/23/2024, 6:25 PMCasey Brooks
02/23/2024, 6:28 PMMutableSet()
(or List()
, MutableMap()
, etc.) all imply a constructor-like behavior, where you get a new distinct object as a return value each time. But this isn’t true, because the factory function returns different implementations of the collection based on how many items are passed to it. In the case that no items passed in to a read-only collection, you are actually given an instance of a singleton EmptySet
, EmptyMap
, EmptyList
, etc. which is not distinct.
A new object isn’t necessarily created with each call, like you’d expect form a constructor, so instead a factory function is more appropriate. And then there are mutable versions of the read-only collections which simply use the same syntax for consistency, even though they do always give a new instance.ephemient
02/23/2024, 6:30 PMArray
and List
constructor-like functions thoughephemient
02/23/2024, 6:31 PMArray
it's an actual constructor, handled by some compiler magic, so let's ignore that for this discussion)ephemient
02/23/2024, 6:33 PMList {}
Set {}
etc. instead of buildList {}
buildSet {}
etc.Casey Brooks
02/23/2024, 6:35 PMKlitos Kyriacou
02/25/2024, 2:53 PMlistOf
and the List
factory function are both factory functions that produce a list, but they have different meanings: if, during the early development of the library, we had just defined List
as the sole factory function, we wouldn't be able to call these two functions with the same parameters but with very different meanings:
val x = listOf(2, { Random.nextInt() })
val x = List(2, { Random.nextInt() })
(That is a very contrived example though.)Joffrey
02/25/2024, 3:01 PMJoffrey
02/25/2024, 3:03 PMCLOVIS
02/26/2024, 8:52 AMA new object isn’t necessarily created with each call, like you’d expect form a constructor, so instead a factory function is more appropriate. And then there are mutable versions of the read-only collections which simply use the same syntax for consistency, even though they do always give a new instance.This would make sense, but the style guide says the opposite:
Factory functions used to create instances of classes can have the same name as the abstract return type:
```interface Foo { /*...*/ }
class FooImpl : Foo { /*...*/ }
fun Foo(): Foo { return FooImpl() }```https://kotlinlang.org/docs/coding-conventions.html#function-names
Klitos Kyriacou
02/26/2024, 2:10 PMList
would always create a new instance because it looks like a constructor call. And indeed it does. List(0) {0}
creates a new empty list instance, while listOf()
returns the existing instance EMPTY_LIST
.