Given that Kotlin is a functional language, there are many instances where a single, immutable value is passed through a series of methods, each of which create a new, changed instance of that value and return it. This is especially true when using copy() on data objects.
For example: given Type A that is a data class, you might have methods:
fun mutateA1(a: A) = a.copy(field1 = field1+1)
fun mutateA2(a:A) = a.copy(field2 = field2*2)
A set of calls to these methods would look like:
mutateA2(mutateA1(a))
(which gets messier with more methods and more parameters)
In Clojure, there is a keyword (technically a macro) called the “thread-first” macro (Clojure - Threading Macros Guide) that assists this scenario:
→ a
mutateA1()
mutateA2()
It would be nice if Kotlin adopted something similar, to encourage this sort of immutable design.
/**
* Imitation of a clojure threading macro.
* *NO* compile time type safety, just like in clojure.
* Not sure whether to be proud or horrified of myself, just as of clojure.
*/
@Suppress("UNCHECKED_CAST")
inline fun <reified R> Any.thread(vararg operations: Function1<*, *>): R =
operations.fold(this) { value, func -> (func as Function1<Any, Any>)(value) } as R
@Test
fun threadingMacroImitationTest() {
10.0.thread<String>(
// Unlike clojure, requires ugly casting when wrapping multi-arity functions.
{ (it as Double).pow(4.0) },
::sqrt,
{ (it as Double).toString() }
) shouldBe "100.0"
}