Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Functional Programming
in Kotlin with Arrow
Emmanuel Nhan - 28/06/2018
/me !
• Backend engineer at Sigfox

• Mostly OOP by day (Java, Spring 😒) but FP enthusiast

• FP by night & evangelization...
Scope
Functional Programming:
Using pure functions
Strongly typed
Using techniques found in Scala
Kotlin (v1.2.x):
Focus o...
Functional Programming
• Functions, high order functions

• Immutable data

• Referential Transparency

• Abstractions

• ...
Kotlin ?
• Hype 🤩

• Language tasting like Java with lots of sugar 🍯
• Inspired by many existing languages

• Runs on JVM ...
Why FP in Kotlin on JVM ?
• When the team is too scared by Scala

• Idioms which make FP possible & enjoyable

• But conce...
Functions
Functions
// Declaring a simple function
fun add(a: Int, b: Int): Int = a + b
// Or
val minus: (Int, Int) -> Int =
{ a, b ...
Extension Functions
• Feature allowing to add functions to an exiting type

// Enriching Int :
fun Int.minus3(): Int = thi...
Immutable Data
Structures
Types: data classes
data class Message(val author: String,
val recipient: String,
val content: String)
declares fields whic...
object
• Allows to declare singletons:

object Bar
• companion object adds methods « to the type itself »

// Declaration
...
Types: hierarchy
Any
Nothing
Every single type declared in the application
Nothing is called the bottom type : it inherits...
Types: Option
sealed class Option<out T>
data class Some<out T>(val t: T): Option<T>()
object None: Option<Nothing>()
// U...
Types: recursive structure
sealed class LinkedList<out A>
data class Cons<A>(
val head: A,
val tail: LinkedList<A>
): Link...
Abstractions
Ad-hoc polymorphism
• Technique popularized by Haskell (typeclasses)

• A set of pure functions to fulfill a contract (laws...
Order Typeclass
interface Order<T> {
/**
* Compare [x] with [y].
* Returns an Int whose sign is:
* - negative if `x < y`
*...
Order Typeclass instance
object IntOrderInstance: Order<Int> {
override fun compare(x: Int, y: Int): Int

= when {
x < y -...
Usage of Order
/**
* Sort [list] in croissant order.
* Typeclass instance passing by parameter
*/
fun <T> sort(list: List<...
Higher Kinds 101
• Let’s say we have a typeclass SomeTC<F>

• Constraint on F : to be a type shaped like SomeType<A>
• Som...
Higher Kind emulation
// Kind definition
interface Kind<out F, out A>
typealias Kind2<F,A,B> = Kind<Kind<F,A>,B>
typealias...
Higher Kind emulation
• Going back to our LinkedList<A>

• Its shape is Kind<F, A>

class ForLinkedList private constructo...
Higher Kinds & Typeclasses
interface Functor<F> {
fun <A, B> map(v: Kind<F, A> ,f: (A) -> B):
Kind<F, B>
}
// Emulation dr...
We can do better
Meet Arrow
• A library based on the principles we just saw

• Inspired by Cats & Scalaz from Scala ecosystem 

• Uses code...
Arrow typeclasses
• Provides extensions methods :

interface Functor<F> {
fun <A, B> Kind<F, A>.map(f: (A) -> B):
Kind<F, ...
Option
val a: Option<Int> = 3.some()
val b: Option<Int> = 5.some()
val res: Option<Int> = a.flatMap {
x -> b.map { it + x ...
Option 2
val a: Option<Int> = 3.some()
val b: Option<Int> = 5.some()
val res = ForOption extensions {
binding {
a.bind() +...
Sample: Validation
// THE CONTEXT
import arrow.core.*
import arrow.data.*
typealias AppRawConfig = MapK<String, String>
fu...
Either & Option
val conf = retrieveConf()
val someParam: Either<String, Int> =
conf.getOption("someParam" ).fold(
{
"Could...
Accumulating failures
• We need a similar structure to Either<L,R> :
Validated<E,A>

• How to accumulate values on the E t...
ValidatedNel
val otherParam: Either<String, Int> = //TODO()
val someParamV: Validated<String, Int> =
Validated.fromEither(...
Accumulating
data class SomeConfig(val a: Int, val b: Int)
val otherParamVNel: ValidatedNel<String, Int> = // …
val result...
More Arrow
• Optics

• Recursion schemes

• Integration with Kotlin coroutines, RxJava, Reactor,…

• IO
• Uses much more K...
Thank you !
Any questions ?
Resources & links
• https://kotlinlang.org/

• https://arrow-kt.io/

• https://gitter.im/arrow-kt/Lobby

• https://typelev...
Upcoming SlideShare
Loading in …5
×

Functional programming in kotlin with Arrow [Sunnytech 2018]

5,077 views

Published on

Slides from my talk about Kotlin & Functional programming with Arrow which I gave at Sunny Tech 2018 (http://sunny-tech.io)
It showcases how Kotlin is a good fit for functional programming, thanks to Arrow.

Published in: Entertainment & Humor
  • Be the first to comment

Functional programming in kotlin with Arrow [Sunnytech 2018]

  1. 1. Functional Programming in Kotlin with Arrow Emmanuel Nhan - 28/06/2018
  2. 2. /me ! • Backend engineer at Sigfox • Mostly OOP by day (Java, Spring 😒) but FP enthusiast • FP by night & evangelization at work • Not FP expert • @nhanmanu on Twitter
  3. 3. Scope Functional Programming: Using pure functions Strongly typed Using techniques found in Scala Kotlin (v1.2.x): Focus on JVM only Idioms to build FP machinery Arrow (v0.7.2): How it works Overview of core
  4. 4. Functional Programming • Functions, high order functions • Immutable data • Referential Transparency • Abstractions • Lazy evaluation
  5. 5. Kotlin ? • Hype 🤩 • Language tasting like Java with lots of sugar 🍯 • Inspired by many existing languages • Runs on JVM ( including Android), JS, Native • Developed by Jetbrains • First class citizen in Android, Spring, Reactor,…
  6. 6. Why FP in Kotlin on JVM ? • When the team is too scared by Scala • Idioms which make FP possible & enjoyable • But concepts are missing : 
 need to emulate them
  7. 7. Functions
  8. 8. Functions // Declaring a simple function fun add(a: Int, b: Int): Int = a + b // Or val minus: (Int, Int) -> Int = { a, b -> a - b} // With generics & high order ! fun <A, B, C> compose(f: (A) ->B, g: (B) ->C ): (A) ->C = { a: A -> g(f(a))} Function definition Return typeParameters
  9. 9. Extension Functions • Feature allowing to add functions to an exiting type // Enriching Int : fun Int.minus3(): Int = this - 3 // Works also with generics fun <A, B, C> ((A, B) ->C).partial(a: A): (B) ->C = {b: B -> this(a, b)} • Using this syntax: 6.minus3() val plus4: (Int) ->Int = ::add.partial(4)
  10. 10. Immutable Data Structures
  11. 11. Types: data classes data class Message(val author: String, val recipient: String, val content: String) declares fields which are not reassignable
  12. 12. object • Allows to declare singletons: object Bar • companion object adds methods « to the type itself » // Declaration class Foo { // ... companion object { fun bar(): Int = TODO() } } // Use Foo.bar()
  13. 13. Types: hierarchy Any Nothing Every single type declared in the application Nothing is called the bottom type : it inherits from all
  14. 14. Types: Option sealed class Option<out T> data class Some<out T>(val t: T): Option<T>() object None: Option<Nothing>() // Usage: val a: Option<Int> = Some(4) val r = when(a){ is Some -> a.t is None -> 0 } Not really pattern matching but… inheritance
  15. 15. Types: recursive structure sealed class LinkedList<out A> data class Cons<A>( val head: A, val tail: LinkedList<A> ): LinkedList<A>() object Nil: LinkedList<Nothing>()
  16. 16. Abstractions
  17. 17. Ad-hoc polymorphism • Technique popularized by Haskell (typeclasses) • A set of pure functions to fulfill a contract (laws) • Abstraction over a general property • No native support in Kotlin (yet)
  18. 18. Order Typeclass interface Order<T> { /** * Compare [x] with [y]. * Returns an Int whose sign is: * - negative if `x < y` * - zero if `x = y` * - positive if `x > y` */ fun compare(x: T, y: T): Int }
  19. 19. Order Typeclass instance object IntOrderInstance: Order<Int> { override fun compare(x: Int, y: Int): Int
 = when { x < y -> -1 x > y -> 1 else -> 0 } }
  20. 20. Usage of Order /** * Sort [list] in croissant order. * Typeclass instance passing by parameter */ fun <T> sort(list: List<T>, O: Order<T>): List<T> = TODO() Sorting requires a property of ordering
  21. 21. Higher Kinds 101 • Let’s say we have a typeclass SomeTC<F> • Constraint on F : to be a type shaped like SomeType<A> • SomeType<A> is a type constructor
 with one parameter: A • Reasoning on theses shapes allows better abstractions
  22. 22. Higher Kind emulation // Kind definition interface Kind<out F, out A> typealias Kind2<F,A,B> = Kind<Kind<F,A>,B> typealias Kind3<F,A,B,C> = Kind<Kind2<F,A,B>,C> Type aliasing: makes code more readable Type constructor parameter Marker type independent of A
  23. 23. Higher Kind emulation • Going back to our LinkedList<A> • Its shape is Kind<F, A> class ForLinkedList private constructor() typealias LListOf<A> = Kind<ForLinkedList, A> sealed class LinkedList<out A>: LListOf<A> { //…
  24. 24. Higher Kinds & Typeclasses interface Functor<F> { fun <A, B> map(v: Kind<F, A> ,f: (A) -> B): Kind<F, B> } // Emulation drawback : downcasting… val l: Kind<ForLinkedList, Int> = //Some call to map() val fixed: LinkedList<Int> = l.fix() // Definition of fix()😱 : fun <A> OptionOf<A>.fix(): Option<A> = this as Option<A> Need to downcast !
  25. 25. We can do better
  26. 26. Meet Arrow • A library based on the principles we just saw • Inspired by Cats & Scalaz from Scala ecosystem • Uses code generation (for now) to reduce boilerplate • Lots of modules & contributors • Integrates with other libraries from the Kotlin ecosystem
  27. 27. Arrow typeclasses • Provides extensions methods : interface Functor<F> { fun <A, B> Kind<F, A>.map(f: (A) -> B): Kind<F, B> } • Still no way to avoid fix() . Go vote for KEEP-87 ! • Provides instances for common datatypes • Uses KAPT to generate boilerplate • Enhanced syntax
  28. 28. Option val a: Option<Int> = 3.some() val b: Option<Int> = 5.some() val res: Option<Int> = a.flatMap { x -> b.map { it + x } }
  29. 29. Option 2 val a: Option<Int> = 3.some() val b: Option<Int> = 5.some() val res = ForOption extensions { binding { a.bind() + b.bind() }.fix() }
  30. 30. Sample: Validation // THE CONTEXT import arrow.core.* import arrow.data.* typealias AppRawConfig = MapK<String, String> fun retrieveConf(): AppRawConfig = TODO() To use Arrow easily
  31. 31. Either & Option val conf = retrieveConf() val someParam: Either<String, Int> = conf.getOption("someParam" ).fold( { "Could not find someParam".left() },{ toParse -> val nullable: Int? = toParse.toIntOrNull() nullable.toOption().fold({ "someParam is not an Int".left() },{ it.right() }) } ) Addition from MapK Extension Method Kotlin feature
  32. 32. Accumulating failures • We need a similar structure to Either<L,R> : Validated<E,A> • How to accumulate values on the E type ? • NonEmptyList<A> or Nel<A> makes sure a list contains at least one element • We will accumulate in Validated<Nel<String>, T>
  33. 33. ValidatedNel val otherParam: Either<String, Int> = //TODO() val someParamV: Validated<String, Int> = Validated.fromEither(someParam) val otherParamV: Validated<String, Int> = Validated.fromEither(otherParam) val someParamVNel: ValidatedNel<String, Int> = someParamV.toValidatedNel() Lifting Either to Validated Transforming the left type to Nel
  34. 34. Accumulating data class SomeConfig(val a: Int, val b: Int) val otherParamVNel: ValidatedNel<String, Int> = // … val result: ValidatedNel<String, SomeConfig> = ValidatedNel.applicative( Nel.semigroup<String>() ) .map(someParamVNel, otherParamVNel){ t -> SomeConfig(t.a, t.b) }.fix()
  35. 35. More Arrow • Optics • Recursion schemes • Integration with Kotlin coroutines, RxJava, Reactor,… • IO • Uses much more Kotlin idioms (delegation,…)
  36. 36. Thank you ! Any questions ?
  37. 37. Resources & links • https://kotlinlang.org/ • https://arrow-kt.io/ • https://gitter.im/arrow-kt/Lobby • https://typelevel.org/cats/typeclasses.html • https://www.pacoworks.com/2018/02/25/simple- dependency-injection-in-kotlin-part-1/

×