Is there a preferred way to approach companion fun...
# functional
j
Is there a preferred way to approach companion function with a functional style ?
Copy code
data class SomeData(val someValue: String) {
  companion object {
    fun someFunction() {}
  }
}

// OR

data class SomeData(val someValue: String) {
  companion object
}

fun SomeData.Companion.someFunction() {}
s
Not sure if this is related to FP šŸ˜… Personally I would always put it in the
companion
itself when possible. I would say follow rule of thumb - simplest solution. It doesn't require an import that way (, and is better for IDEA).
j
Well I donā€™t really know where to put the limit of ā€œtry to have as much pure function as you can, avoid classes since it could hold internal variable that could turn your code in a non-pure way over timeā€. So this fall into this grey area for me where Iā€™m not sure what to prefer
s
since it could hold internal variable that could turn your code in a non-pure way over time
I guess I'm more in the camp of "this should be caught at PR review time". But even then, this doesn't suffer from that problem since
companion object
is "static" so it doesn't have access to any "mutable state" that the class could potentially hold. I am also in favor of adding
fun toOther(): OtherDataClass
inside
SomeData
rather than an extension function for the same rationale of "not needing an import". Simple rule of thumb applies here:
data class
should only have `val`'s in the constructor, or pure functions inside the body or
companion object
.
Everything in Kotlin is grey area IMO. Even most OOP code has a lot of FP hidden. ā€¢
suspend
is a functional concept ā€¢ KotlinX Coroutines is an FP concurrency library if you ask me. It follows all the same principles as
IO
of other FP languages. ā€¢
Collections.kt
exists out of FP combinators. ā€¢ Nullable types are derived from
Option
, with some slight differences and trade-offs (nested nullable type problem only being problematic in generic code).