Threading a parameter through multiple method calls

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.

You can use extension methods

fun A.mutate1() = ...
fun A.mutate2() = ...

a.mutate1()
 .mutate2()

Just for the hell of it…

/**
 * 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"
    }

1 Like

You could use let. It’s more verbose than Clojure, but you don’t have to define anything additional :

a.let { it.copy(field1 = ...) }
 .let { it.copy(field2 = ...) }
1 Like