Edson Hilios
September 29, 2017
700

Either, Some or None: An introduction to monadic structures and functional programming

We will discuss and understand the monadic structures, going through the most important monads, it's operations and main advantages of the functional programming using Scala, Kotlin, Swift, a little bit of Clojure and why not JavaScript.

During the talk we should also realize why concepts as laziness and immutable data are the cornerstone of high throughput threaded systems and how its guarantee reliability and performance.

By the end of the day you should know by heart the main monads and how to use them solve different day-by-day problems and deeply in love with functional programming.

Edson Hilios

September 29, 2017

Transcript

1. Either, Some or None
An introduction to monadic structures and
functional programming
September 29th, São Paulo, Brazil

2. Edson Hilios
MSc. Transp. Engineering & BSc. Engineering
Software Engineer at _____

3. What I would like to know about

● Implemented in major modern languages:
● Provides simple ways of express complex computation;

5. Goals
● A soft theory of Monad
● Monodic structures and operations
● Real use cases
● Recap

7. If this than that
should execute.
It allows you to handle and route different inputs/outputs without
repeating yourself.

8. It's a design pattern to describe and
manipulate flows of data

● Composable
● Polymorphic
● Immutable
● Lazily evaluated

● Map
● Filter
● Aggregate
● Group

trait Monoid[A] {
// The identity
def get[A]: A
// The functor
def map[B](f: A => B): Monad[B]
// The bind
}
Scala

13. The optional pattern
val aString: String = "Hello, world!"
val len: Int = aString.length
Scala

14. The optional pattern
val aString: String = null
val len: Int = aString.length
//=> java.lang.NullPointerException
Scala

15. The optional pattern
val maybeString: Option[String] = Some("Hello, world!")
val maybeLen: Int = maybeString.map(_.length).getOrElse(-1)
Scala

16. The optional pattern
val maybeString: String? = "Hello, world!"
val maybeLen = maybeString?.length ?: -1
Kotlin

17. The optional pattern
let maybeString: String? = "Hello, world!"
let maybeLen = maybeString.length ?? -1
Swift

(some-> (maybe-a-result from-db)
(then-do-something)
(then-another)
(and-finishes))
Clojure
Execute if last result is not nil
It will return the value or nil
Pass the result to the next fn

19. Call me Maybe
s::String -> Maybe String
s "" = Nothing
s x = Just x

val query: Option[String] = Option(myNullableOutput)
query match {
case Some(q) => myTable.filter(_.name == q)
case None => myTable.all()
}
Scala

21. Exception handling
val maybeAnOperation: Try[Any] = Try {
potentiallyHarmfulOperation()
} match {
case Success(s: Any) => ???
case Failure(e: ArithmeticException) => ???
case Failure(e: Exception) => ???
}
Scala

22. The functor
def firstFunctor(x: Any): Try[String] = ???
def secondFunctor(y: String): Try[Int] = ???
def thirdFunctor(z: Int): Try[MyType] = ???
maybeAnException
.map(firstFunctor)
.map(secondFunctor)
.map(thirdFunctor)
Try[Any]
Try[Try[String]]
Try[Try[Try[Int]]]
Try[Try[Try[Try[MyType]]]]
Scala

23. Bind operations
def firstFunctor(x: Any): Try[String] = ???
def secondFunctor(y: String): Try[Int] = ???
def thirdFunctor(z: Int): Try[MyType] = ???
maybeAnException
.flatMap(firstFunctor)
.flatMap(secondFunctor)
.flatMap(thirdFunctor)
Try[Any]
Try[String]
Try[Int]
Try[MyType]
Scala

24. Either this or that
val json: Either[JsError, JsSuccess] = parse("""{"foo": "bar"}""")
json match {
case JsSuccess(o) => println("OK")
case JsError(err) => println(err.list)
}
Scala

25. Applicative functor
def nonEmpty(s: Option[String]): Validated[Invalid, Valid]
val isValid = (
nonEmpty("Some string") |@|
nonEmpty("") |@|
nonEmpty("Other str") |@|
nonEmpty(null)
).fold(left => false, rigth => true)
Cats

26. Valid
Invalid("Cannot be blank")
Valid
Invalid("Cannot be null")
Holomorphism
{
"1": "Some string",
"2": "",
"3": "Other str",
"4": null
}
JSON

27. Right or left identity
def httpRequest(input: Either[Valid, Invalid]): HttpResponse =
input.fold(
right => HttpResponse(StatusCodes.OK))
Scala

28. Future pattern
(def eventualString
"Hello, async!")
@eventualString
;; => Returns Hello, async after 1s
Clojure

29. Asynchronous operations
"Hello, async!"
} map { result =>
result.length
}
eventualLength.run() // => Eventually returns 13 after 1s
Scalaz

30. Sequential or concurrent
.run()
).run()
Scalaz
Scalaz

31. Assigning callbacks
.runAsync {
case Success(s) => // Perform side effects
case Failure(e) => // Do something on failure
}
Scalaz

let eventualResponse = new Promise(function() {
setTimeout(() => resolve("Hello, world!"), 2000)
})
eventualResponse
.then(applyFunctor)
.then(msg => console.log("Apply side-effects!"))
ES2016

33. The observable pattern
val observer = new Observer[Any] {
def onNext(elem: Any): Future[Ack] =
Continue
def onError(ex: Throwable): Unit =
ex.printStackTrace()
def onComplete(): Unit =
println("Completed")
}
Monix

34. Observable operations
● Group by batches or time intervals;
● Fork and merge streams;
● Handle errors and apply retry strategies;
● Delay execution and back-pressure.

35. Becoming reactive
Rx.Observable.webSocket('ws://localhost:8000')
.retryWhen((errors) => {
return Rx.Observable.timer(5000) // retry in 5 secs
})
.groupBy((msg) => msg.category)
.throttle(1000) // One message per sec and discard the rest
.subscribe((msgs) => console.log(msgs))
ES2016

● Maybe is useful to handle failures scenarios;
● Either for validations and data deserialization;
● Future lets you create asynchronous operations;

● SwiftZ and Runes for Swift
● Kathegory for Kotlin
● Scalaz, Cats and Monix for Scala
● ReactiveX (aka Rx): Scala, C#, C++, Kotlin, Swift and many others

38. Homework