What's your opinion on using top level functions w...
# announcements
u
What's your opinion on using top level functions with capital letter as factory functions? I notice people doing this more and more
Copy code
fun User(...) : User? {
   // if invalid input return null
   return User(..)
}

data class User(...)
a
Well, this is a personal opinion but mostly inspired by the kotlin stdlib 1. If I have an interface and also I need to provide a concrete implementation, I use a Capital letter function as a top level builder function like so
Copy code
interface Human

private class Person(val name:String):Human

fun Human(name: String):Human = Person(name)
2. How ever if I have a class and all I want to check is validity, I mainly use companion invoke operator functions
Copy code
data class User internal constructor(
    val name: String,
    val phone: String,
    val email: String
) {
    companion object {
        operator fun invoke(name: String,phone:String): User { . . .}
        operator fun invoke(name: String,email: String):User { . . .}
        operator fun invoke(name: String,email:String,phone:String): User {. . .}
    }
}
3. If I am building UI components/composables, I use Capital letter functions. It makes the code easy to follow through
Copy code
// compose
@Compose
fun UserView(u:User) = Column {
    Text(content = u.name)
    Text(content = u.phone)
    Text(content = u.email)
}

// kotlin react
fun RBuilser.UserView(u: User) = Flex {
    Text(content = u.name)
    Text(content = u.phone)
    Text(content = u.email)
}
a
Could do userOf
n
I feel like it's a bit misleading to write things that look like a constructor but don't have the same signature (return nullable)
I'd use a different name in that case
If I was returning non nullable I'd still prefer secondary constructors unless there was a specific reason. Top level function vs companion invoke ("smart constructor"), is interesting
The problem with top level functions is that you have to have other public constructors, but if that's the case then makes more sense to use it over a smart constructor afaics
a
This case is described in Kotlin Coding Conventions so it is totally fine: https://kotlinlang.org/docs/reference/coding-conventions.html#function-names
2
u
@Arkadii Ivanov it talks about abstract factort though