From 3f24ce3713c04e03bbb887e1dd15886137027923 Mon Sep 17 00:00:00 2001 From: Jose Gutierrez Date: Mon, 13 Mar 2023 16:17:57 +0100 Subject: [PATCH 1/3] Deprecate `Result` `zip` method in favour of DSL --- .../commonMain/kotlin/arrow/core/Result.kt | 103 +++++++++++++++++- .../kotlin/arrow/core/ResultTest.kt | 20 +++- 2 files changed, 118 insertions(+), 5 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt index 1a69860099b..36c6a1839a7 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt @@ -1,4 +1,5 @@ @file:OptIn(ExperimentalContracts::class) + package arrow.core import kotlin.Result.Companion.failure @@ -53,6 +54,13 @@ public inline fun Result.redeemWith( /** * Combines n-arity independent [Result] values with a [transform] function. */ +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip(b: Result, transform: (A, B) -> C): Result { contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } return zip( @@ -68,6 +76,13 @@ public inline fun Result.zip(b: Result, transform: (A, B) -> C): ) { a, b, _, _, _, _, _, _, _, _ -> transform(a, b) } } +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip(b: Result, c: Result, transform: (A, B, C) -> D): Result { contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } return zip( @@ -83,6 +98,13 @@ public inline fun Result.zip(b: Result, c: Result, transfo ) { a, b, c, _, _, _, _, _, _, _ -> transform(a, b, c) } } +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind(), d.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip( b: Result, c: Result, @@ -103,6 +125,13 @@ public inline fun Result.zip( ) { a, b, c, d, _, _, _, _, _, _ -> transform(a, b, c, d) } } +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip( b: Result, c: Result, @@ -122,6 +151,13 @@ public inline fun Result.zip( } } +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip( b: Result, c: Result, @@ -143,6 +179,13 @@ public inline fun Result.zip( } } +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip( b: Result, c: Result, @@ -153,9 +196,26 @@ public inline fun Result.zip( transform: (A, B, C, D, E, F, G) -> H ): Result { contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zip(b, c, d, e, f, g, UnitResult, UnitResult, UnitResult) { a, b, c, d, e, f, g, _, _, _ -> transform(a, b, c, d, e, f, g) } + return zip(b, c, d, e, f, g, UnitResult, UnitResult, UnitResult) { a, b, c, d, e, f, g, _, _, _ -> + transform( + a, + b, + c, + d, + e, + f, + g + ) + } } +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip( b: Result, c: Result, @@ -167,9 +227,27 @@ public inline fun Result.zip( transform: (A, B, C, D, E, F, G, H) -> I ): Result { contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zip(b, c, d, e, f, g, h, UnitResult, UnitResult) { a, b, c, d, e, f, g, h, _, _ -> transform(a, b, c, d, e, f, g, h) } + return zip(b, c, d, e, f, g, h, UnitResult, UnitResult) { a, b, c, d, e, f, g, h, _, _ -> + transform( + a, + b, + c, + d, + e, + f, + g, + h + ) + } } +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip( b: Result, c: Result, @@ -182,10 +260,29 @@ public inline fun Result.zip( transform: (A, B, C, D, E, F, G, H, I) -> J ): Result { contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } - return zip(b, c, d, e, f, g, h, i, UnitResult) { a, b, c, d, e, f, g, h, i, _ -> transform(a, b, c, d, e, f, g, h, i) } + return zip(b, c, d, e, f, g, h, i, UnitResult) { a, b, c, d, e, f, g, h, i, _ -> + transform( + a, + b, + c, + d, + e, + f, + g, + h, + i + ) + } } @Suppress("UNCHECKED_CAST") +@Deprecated( + "Prefer using the inline result DSL", + ReplaceWith( + "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind(), k.bind()) }", + "arrow.core.raise.result" + ) +) public inline fun Result.zip( b: Result, c: Result, diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt index af57748b263..7eb2eb9a50e 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt @@ -1,15 +1,31 @@ package arrow.core +import arrow.core.raise.result +import arrow.core.test.result import io.kotest.core.spec.style.StringSpec import io.kotest.matchers.shouldBe +import io.kotest.property.Arb +import io.kotest.property.arbitrary.int +import io.kotest.property.checkAll class ResultTest : StringSpec({ - + "null zip null" { val x = Result.success(null) x.zip(x) { y, z -> (y?.plus(z ?: -2)) ?: -1 } shouldBe Result.success(-1) } - + + "result DSL + bind usage should return the same as deprecated zip" { + checkAll(Arb.int(), Arb.int(), Arb.int()) { x, y, z -> + val resX = Result.success(x) + val resY = Result.success(y) + val resZ = Result.success(z) + val zip = resX.zip(resY, resZ) { a, b, c -> a + b + c } + val dsl = result { resX.bind() + resY.bind() + resZ.bind() } + dsl shouldBe zip + } + } + }) From 12e580a0d993a502e250ab19472610dce2bfb29b Mon Sep 17 00:00:00 2001 From: Jose Gutierrez Date: Thu, 16 Mar 2023 13:03:32 +0100 Subject: [PATCH 2/3] Remove test This test does no make sense. Both methods do no return the same value. --- .../src/commonTest/kotlin/arrow/core/ResultTest.kt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt index 7eb2eb9a50e..a824b3b4d60 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/ResultTest.kt @@ -17,15 +17,4 @@ class ResultTest : StringSpec({ } shouldBe Result.success(-1) } - "result DSL + bind usage should return the same as deprecated zip" { - checkAll(Arb.int(), Arb.int(), Arb.int()) { x, y, z -> - val resX = Result.success(x) - val resY = Result.success(y) - val resZ = Result.success(z) - val zip = resX.zip(resY, resZ) { a, b, c -> a + b + c } - val dsl = result { resX.bind() + resY.bind() + resZ.bind() } - dsl shouldBe zip - } - } - }) From 8e6687c9dbee117cbf2a5a6b897707ba8123ef44 Mon Sep 17 00:00:00 2001 From: Jose Gutierrez Date: Thu, 16 Mar 2023 13:18:00 +0100 Subject: [PATCH 3/3] Add proper deprecation message --- .../commonMain/kotlin/arrow/core/Result.kt | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt index 36c6a1839a7..c64f4dea181 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Result.kt @@ -8,6 +8,10 @@ import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract +internal const val deprecateZip: String = + "Prefer using the inline result DSL + bind(). Please, be aware that all the errors are no longer accumulated, just the first error found is considered." + + "In case you think this behaviour should stay, please provide feedback and your use-case on https://github.com/arrow-kt/arrow/issues" + @PublishedApi internal inline val UnitResult: Result inline get() = success(Unit) @@ -55,7 +59,7 @@ public inline fun Result.redeemWith( * Combines n-arity independent [Result] values with a [transform] function. */ @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind()) }", "arrow.core.raise.result" @@ -77,7 +81,7 @@ public inline fun Result.zip(b: Result, transform: (A, B) -> C): } @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind()) }", "arrow.core.raise.result" @@ -99,7 +103,7 @@ public inline fun Result.zip(b: Result, c: Result, transfo } @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind(), d.bind()) }", "arrow.core.raise.result" @@ -126,7 +130,7 @@ public inline fun Result.zip( } @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind()) }", "arrow.core.raise.result" @@ -152,7 +156,7 @@ public inline fun Result.zip( } @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind()) }", "arrow.core.raise.result" @@ -180,7 +184,7 @@ public inline fun Result.zip( } @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind()) }", "arrow.core.raise.result" @@ -210,7 +214,7 @@ public inline fun Result.zip( } @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind()) }", "arrow.core.raise.result" @@ -242,7 +246,7 @@ public inline fun Result.zip( } @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind()) }", "arrow.core.raise.result" @@ -277,7 +281,7 @@ public inline fun Result.zip( @Suppress("UNCHECKED_CAST") @Deprecated( - "Prefer using the inline result DSL", + deprecateZip, ReplaceWith( "result {transform(this.bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind(), k.bind()) }", "arrow.core.raise.result"