Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Learning functional programming the hard way wi...

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Avatar for voiser voiser
November 23, 2019

Learning functional programming the hard way with Spark

Avatar for voiser

voiser

November 23, 2019

Other Decks in Programming

Transcript

  1. MAD · NOV 22-23 · 2019 David Muñoz - @voiser

    Learning FP to the donkey the hard way with
  2. MAD · NOV 22-23 · 2019 You probably have heard

    of the FP Way: Pure functions Immutability HOFs map, flatmap, foldLeft…
  3. MAD · NOV 22-23 · 2019 val counts = mutable.Map[String,

    Int]() foreach(word in words) { val currentCount = counts.getOrElse(word, 0) counts.put(word, currentCount + 1) } pseudocode
  4. MAD · NOV 22-23 · 2019 What if we have

    trillions of words? Let’s use Spark!
  5. MAD · NOV 22-23 · 2019 Driver Worker Worker Worker

    Worker RDD i really like scala i want to learn to code in scala as soon as I can
  6. MAD · NOV 22-23 · 2019 RDD[T]. map(f: (T) !=>

    U): RDD[U] RDD[T]. !flatMap(f: (T) !=> TraversableOnce[U]): RDD[U] RDD[T]. reduce(f: (T, T) !=> T): T RDD[T]. fold(z: T)(f: (T, T) !=> T): T
  7. MAD · NOV 22-23 · 2019 val counts = mutable.Map[String,

    Int]() rddWords.foreach { word => val currentCount = counts.getOrElse(word, 0) counts.put(word, currentCount + 1) } pseudocode
  8. MAD · NOV 22-23 · 2019 Driver Worker Worker Worker

    Worker RDD i really like scala i want to learn to code in scala as soon as I can Map[String, Int]() Map[String, Int]() Map[String, Int]() Map[String, Int]() Map[String, Int]()
  9. MAD · NOV 22-23 · 2019 Let’s represent a word-count

    like an object: word count hello 87
  10. MAD · NOV 22-23 · 2019 Example: “hello hello world”

    word count world 1 word count hello 1 word count hello 1
  11. MAD · NOV 22-23 · 2019 word count hello A+B

    word count hello B word count hello A Let’s define a combination operation: * =
  12. MAD · NOV 22-23 · 2019 word count hello A

    Let’s define a combination operation: word count world B word count hello A world B * =
  13. MAD · NOV 22-23 · 2019 Example: “hello hello world”

    word count world 1 word count hello 1 word count hello 1
  14. MAD · NOV 22-23 · 2019 word count hello 1

    word count world 1 word count hello 1 *
  15. MAD · NOV 22-23 · 2019 Semigroup If a type

    A can form a Semigroup it has an associative binary operation. trait Semigroup[A] { def combine(x: A, y: A): A } Associativity means the following equality must hold for any choice of x, y, and z. combine(x, combine(y, z)) = combine(combine(x, y), z) https://typelevel.org/cats/typeclasses/semigroup.html
  16. MAD · NOV 22-23 · 2019 val result = rdd

    .map(x => (x, 1)) .reduceByKey((a, b) => a + b)
  17. MAD · NOV 22-23 · 2019 val result = rdd

    .map(x => (x, 1)) .reduceByKey((a, b) => a + b) word count hello 1 * = word count hello A world C word count hello B scala D word count hello A+B world C scala D
  18. MAD · NOV 22-23 · 2019 Worker Worker word count

    world 1 word count hello 1 word count hello 1
  19. MAD · NOV 22-23 · 2019 Worker Worker word count

    world 1 word count hello 1 word count hello 1 word count hello 2 word count hello 2 world 1
  20. MAD · NOV 22-23 · 2019 Worker Worker word count

    world 1 word count hello 1 word count hello 1
  21. MAD · NOV 22-23 · 2019 Worker Worker word count

    world 1 word count hello 1 word count hello 1 word count hello 2 world 1 word count hello 1 world 1
  22. MAD · NOV 22-23 · 2019 WordCount as a semigroup

    class WordCount … { !// represents a set of (word, count) } def combine(a: WordCount, b: WordCount): WordCount = !// combines to WordCount into one def combineMany(xs: List[WordCount]): WordCount = ???
  23. MAD · NOV 22-23 · 2019 Living without side effects

    is a dream. Seriously. It’s not real.
  24. MAD · NOV 22-23 · 2019 Living without side effects

    is a dream. Seriously. It’s not real. Face it, vegans functional programmers!!
  25. MAD · NOV 22-23 · 2019 RDD i want to

    learn scala f f f f f made up numbers, doesn’t matter RDD 5 8 ???? 4 19
  26. MAD · NOV 22-23 · 2019 val result = words

    .map { w !=> w.length } .map { l !=> 1. / (l - 1) } .foreach(println)
  27. MAD · NOV 22-23 · 2019 val result = words

    .map { w !=> w.length } .map { l !=> if (l !!= 1) 1 / (l - 1) else ??? } .foreach(println) val result = words .map { w !=> w.length } .map { l !=> try { 1 / (l - 1) } catch { case e:Exception !=> ??? } } .foreach(println)
  28. MAD · NOV 22-23 · 2019 Spark is not very

    functional about this. Let’s help him. Describing the problem is the key to control it.
  29. MAD · NOV 22-23 · 2019 trait Try[T] { def

    map(f: T !=> U): Try[U] } class Success[T](t: T) extends Try[T] {…} class Failure[T] extends Try[T] {…} Sum type
  30. MAD · NOV 22-23 · 2019 “hello” “hello” 5 map(_.length)

    Try(value) 6 map(_ + 1) 6.0 map(_.to!Float) ERROR map(_ / 0) map(_.to!Float) map(_ + 1)
  31. MAD · NOV 22-23 · 2019 Functor trait Functor[F[_]] {

    def map[A, B](fa: F[A])(f: A !=> B): F[B] } A Functor instance must obey two laws: •Composition: ◦fa.map(f).map(g) = fa.map(f.andThen(g)) •Identity: ◦fa.map(x !=> x) = fa https://typelevel.org/cats/typeclasses/functor.html
  32. MAD · NOV 22-23 · 2019 The problem with Functors

    def combine(ta: Try[Int], tb: Try[Int] = ta.map(a !=> tb.map(b !=> a + b))
  33. MAD · NOV 22-23 · 2019 The problem with Functors

    def combine(ta: Try[Int], tb: Try[Int]: Try[Try[Int]] = ta.map(a !=> tb.map(b !=> a + b))
  34. MAD · NOV 22-23 · 2019 Monad trait Monad[M[_]] {

    def !flatMap[A, B](ma: M[A])(f: A !=> M[B]): M[B] def unit[A](x: A): M[A] } A Monad instance must obey three laws: •Associativity: ◦m.flatMap(f).flatMap(g) == m.flatMap(x => f(x).flatMap(g)) •Left Identity: ◦unit(x).!flatMap(f) !== f(x) •Right Identity: ◦m.!flatMap(unit) !== m
  35. MAD · NOV 22-23 · 2019 Monads compose def combine(ta:

    Try[Int], tb: Try[Int]: Try[Int] = ta.!flatMap(a !=> tb.map(b !=> a + b))
  36. MAD · NOV 22-23 · 2019 Monads compose def combine(ta:

    Try[Int], tb: Try[Int]: Try[Int] = for { a !<- ta b !<- tb } yield a + b
  37. MAD · NOV 22-23 · 2019 RDD[T]. map(f: (T) !=>

    U): RDD[U] RDD[T]. !flatMap(f: (T) !=> TraversableOnce[U]): RDD[U] RDD[T]. reduce(f: (T, T) !=> T): T RDD[T]. fold(z: T)(f: (T, T) !=> T): T Functor Monad??? Semigroup Monoid
  38. MAD · NOV 22-23 · 2019 def foldLeft [B](z: B)(op:

    (B, A) ⇒ B): B def foldRight[B](z: B)(op: (A, B) ⇒ B): B
  39. MAD · NOV 22-23 · 2019 Sorry for the brasa

    New York 3537 36th St +1 (646) 403-3104 Madrid Alameda, 22 +34 910 754 276 www.meaningcloud.com