Kotlin allows to name a function same as an existing class, e.g. HashSet
with initializer function could be implemented like this:
fun <T> HashSet(n : Int, fn: (Int) -> T) = HashSet<T>(n).apply {
repeat(n) {
add(fn(it))
}
}
When used, it looks like a normal HashSet
constructor:
var real = HashSet<String>()
var fake = HashSet(5) { "Element $it" }
Should this be avoided or encouraged and why?
UPD
In the updated coding conventions, there's a section on this topic:
Factory functions
If you declare a factory function for a class, avoid giving it the same name as the class itself. Prefer using a distinct name making it clear why the behavior of the factory function is special. Only if there is really no special semantics, you can use the same name as the class.
Example:
class Point(val x: Double, val y: Double) { companion object { fun fromPolar(angle: Double, radius: Double) = Point(...) } }
The motivation I described below, though, seems to still hold.
As said in documentation about the naming style:
If in doubt default to the Java Coding Conventions such as:
- methods and properties start with lower case
One strong reason to avoid naming a function same to a class is that it might confuse a developer who will use it later, because, contrary to their expectations:
open
)new HashSet(n, it -> "Element " + it)
is an error)HashSet(n) { "Element $it" }
will construct not a HashSet
but, for example, a LinkedHashSet
It's better to show it explicitly that it's a factory function, not a constructor, to avoid this confusion.
Naming a function same to a class is generally avoided in stdlib, too. Given SomeClass
, in stdlib a preferred naming style for factory functions is someClassOf
, someClassBy
or whatever explains the semantics of the function best. The examples:
generateSequence { ... }
and sequenceOf(...)
lazy { ... }
and lazyOf(...)
compareBy { ... }
listOf(...)
, setOf(...)
, mapOf(...)
So, one should definitely have strong reason to have a function mimic a constructor.
Instead, a function's name might tell a user more (even everything) about its usage.