@vergauwen_simon
KotlinConf’23
Amsterdam
Arrow’s 2.0
Trajectory
Simon
Vergauwen
Xebia Functional
Slide 2
Slide 2 text
ΛRROW
Who am I?
@vergauwen_simon
Slide 3
Slide 3 text
Arrow’s 2.0 Trajectory
Arrow’s
history
Complexity
of FP
Evolving
(OSS) APIs
Embracing
Language
Eco-system
ΛRROW
Slide 4
Slide 4 text
Arrow’s History
Oct 2017
March 2017
FineCinnamon/Katz
Dec 2017
arrow-kt
June 2017
Kategory
March 2013
MarioAriasC/funKTionale
Sept 2017
nomisRev/optikal
ΛRROW
Slide 5
Slide 5 text
ΛRROW
Arrow’s History
Typeclasses &
Higher Kinded
Types
< 0.12.x
Slide 6
Slide 6 text
Complexity of Higher-Kinded Types
interface GistsApi {
fun publicGistsForUser(username: String): Kind
>
}
interface Logger {
fun log(msg: String): Kind
}
ΛRROW
Slide 7
Slide 7 text
Complexity of Higher-Kinded Types
fun main() {
GistsApi(MonoK.async(), MonoKLogger, HttpClient.newHttpClient())
.publicGistsForUser("nomisRev")
.fix()
.mono
.block()
.let(
::
println)
}
ΛRROW
Slide 8
Slide 8 text
Complexity of Higher-Kinded Types
fun main() {
GistsApi(IO.async(),
...
)
//
Arrow Fx IO
GistsApi(DeferredK.async(),
...
)
//
KotlinX Coroutines Deferred
GistsApi(SingleK.async(),
...
)
//
RxJava Single
}
ΛRROW
Slide 9
Slide 9 text
Arrow’s History
Typeclasses &
Higher Kinded
Types
Rehaul of
Arrow
< 0.12.x
0.12.x
ΛRROW
Slide 10
Slide 10 text
Complexity of FP
Steep learning curve Non-idiomatic Foreign concepts,
no language support
ΛRROW
Slide 11
Slide 11 text
Suspend to the rescue
interface GistsApi {
suspend fun publicGistsForUser(username: String): List
}
interface Logger {
suspend fun log(msg: String): Unit
}
ΛRROW
Slide 12
Slide 12 text
Suspend to the rescue
fun main() {
val api = GistApi(Logger.Default, HttpClient.newHttpClient())
runBlocking { api.publicGistsForUser("nomisRev") }
mono { api.publicGistsForUser("raulraja") }
scope.future { api.publicGistsForUser("serras") }
// ...
}
ΛRROW
Slide 13
Slide 13 text
Arrow’s History
Typeclasses &
Higher Kinded
Types
Rehaul of
Arrow
< 0.12.x
0.12.x
Suspend &
Kotlin
Idiomatic
1.x.x
ΛRROW
Slide 14
Slide 14 text
Wrapper specific code
fun GithubUser.process(): Either =
if (login.isNotEmpty()) ProcessedUser(this).right()
else ProcessingFailed.left()
ΛRROW
Slide 15
Slide 15 text
Embracing DSLs
fun GithubUser.process(): Either =
either.eager {
ensure(login.isNotEmpty()) { ProcessingFailed }
ProcessedUser(this@process)
}
ΛRROW
Slide 16
Slide 16 text
Traverse & co
fun List.processAll(): Either>
=
traverse(GithubUser
::
process)
ΛRROW
Arrow’s History
Typeclasses &
Higher Kinded
Types
Rehaul of
Arrow
< 0.12.x
0.12.x
Suspend &
Kotlin
Idiomatic
Small Uniform
APIs & learning
curve
1.x.x
2.x.x
ΛRROW
Slide 19
Slide 19 text
DSLs and smart-contracts
val res: Either = either {
val x: Int? = null
ensureNotNull(x) { "X was zero" }
x + 1
}
ΛRROW
Slide 20
Slide 20 text
Idiomatic API names
inline fun Either.getOrElse(default: (A)
->
B): B
fun Either.getOrNull(): B?
inline fun Either.onRight(action: (right: B)
-
>
Unit): Either
fun Either.leftOrNull(): A?
inline fun Either.onLeft(action: (left: A)
->
Unit): Either
ΛRROW
Slide 21
Slide 21 text
Context receivers
context(Raise)
fun GithubUser.process(): ProcessedUser {
ensure(login.isNotEmpty()) { ProcessingFailed }
return ProcessedUser(this)
}
context(Raise)
fun List.processAll(): List =
map { it.process() }
ΛRROW
Evolving APIs
Community
feedback
Iteration makes
perfect
Breaking
Changes
ΛRROW
Slide 25
Slide 25 text
IntelliJ
@Deprecated(
RedundantAPI + "Prefer the new recover API",
ReplaceWith("recover { a
->
f(a).bind() }", "arrow.core.recover")
)
inline fun Either.handleErrorWith(f: (A)
->
Either): Either
ΛRROW
OpenRewrite
./gradlew :sample:rewriteRun
> Task :sample:rewriteRun
Validating active recipes
Parsing sources from project sample
All sources parsed, running active recipes: arrow.RaiseRefactor
Changes have been made to sample/src/main/kotlin/org/example/example.kt by:
arrow.RaiseRefactor
org.openrewrite.java.ChangeMethodName:
..
.
org.openrewrite.java.ChangeType:
.
..
Please review and commit the results.
ΛRROW
Slide 30
Slide 30 text
ΛRROW
Large-scale automated refactoring
Experimental Kotlin Support
Support JVM & commonMain
Friendly & helpful community
First Arrow recipe
OpenRewrite
Slide 31
Slide 31 text
Documentation ΛRROW
Slide 32
Slide 32 text
Migration Guide ΛRROW
Slide 33
Slide 33 text
Eco System ΛRROW
Slide 34
Slide 34 text
Community ΛRROW
Slide 35
Slide 35 text
Community
https://slack-chats.kotlinlang.org/c/arrow https://github.com/arrow-kt
ΛRROW
Slide 36
Slide 36 text
Visit us at the booth to talk
to Arrow contributors &
Xebia Functional and get
discount on courses.
__
Slide 37
Slide 37 text
Thank you,
and don’t forget
to vote
@vergauwen_simon
KotlinConf’23
Amsterdam