Explain FP like Richard Feynman

Mateusz Kubuszok

Richard Feynman

Feynman on bongos

Some serious pics to contrast with Feynman playing a bongo

Nuclear explosion in Los Alamos
Feynman diagram
Challenger disaster

Feynman diagrams

Feynman wobbling plate

Keep it fun

Feynman dancing
Feynman's painting

Reviewing student’s books

Type of energy

Description

Mechanical

the sum of macroscopic translational and rotational kinetic and potential energies

Electric

potential energy due to or stored in electric fields

Magnetic

potential energy due to or stored in magnetic fields

Gravitational

potential energy due to or stored in gravitational fields

Chemical

potential energy due to chemical bonds

Ionization

potential energy that binds an electron to its atom or molecule

Nuclear

potential energy that binds nucleons to form the atomic nucleus (and nuclear reactions)

Chromodynamic

potential energy that binds quarks to form hadrons

Elastic

potential energy due to the deformation of a material (or its container) exhibiting a restorative force

Mechanical wave

kinetic and potential energy in an elastic material due to a propagated deformational wave

Sound wave

kinetic and potential energy in a fluid due to a sound propagated wave (a particular form of mechanical wave)

Radiant

potential energy stored in the fields of propagated by electromagnetic radiation, including light

Rest

potential energy due to an object’s rest mass

Thermal

kinetic energy of the microscopic motion of particles, a form of disordered equivalent of mechanical energy

  • don’t explain things you try to explain using (even indirectly) things you want to explain

  • abstraction is derived from specifics - not the other way round

Question about magnets

Fucking magnets
  • not everyone has a CS background

  • not everyone has any mathematical background

  • if we want to teach someone a formal definition, we need to make sure they know the whole foundation they need before - and that takes time to adjust

Example

Something classic - a monad tutorial!

Typical infamous approaches

  • monoid in the category of endofunctors

  • monad is like taco/burrito/etc

  • so we have this nice little type class

Let’s tell a story!

I have side effects

def readLine: String = ???
def writeLine(line: String): Unit = ???
def curl(url: URL): String = ???

Let’s return pure value instead!

sealed trait SideEffect[A]

final case class ReadLine()
  extends SideEffect[String]

final case class WriteLine(line: String)
  extends SideEffect[Unit]

final case class Curl(url: URL)
  extends SideEffect[String]

Hmm, we need to combine them somehow…​

sealed trait IO[A] {

  def map[B](f: A => B): IO[B] = ???
}
object IO {

  def readLine: IO[String] = ???
  def writeLine(line: String): IO[Unit] = ???
  def curl(url: URL): IO[String] = ???
}

At first, let’s create suspended side-effect computation!

final case class Suspend[A](se: SideEffect[A])
  extends IO[A]

object IO {
  def readLine: IO[String] =
    Suspend(ReadLine())
  def writeLine(line: String): IO[Unit] =
    Suspend(WriteLine(line))
  def curl(url: URL): IO[String] =
    Suspend(Curl(url))
}

Now, let’s add ability to map!

sealed trait IO[A] {

  def map[B](f: A => B): IO[B] = Map(this, f)
}

final case class Map[A, B](ioa: IO[A], f: A => B)
  extends IO[B]

Are we done?

val writeTest: IO[Unit] = IO.writeLine("test")
// yay!
val getData: IO[String] = IO.readLine.map("we got: " + _)
// yay!
val echo: IO[IO[Unit]] = IO.readLine.map(IO.writeLine)
// shit!

We need some flatten

val echo: IO[Unit] = IO.readLine.map(IO.writeLine).flatten

Or do we?

val echo: IO[Unit] = IO.readLine.flatMap(IO.writeLine)

Let’s replace map with flatMap…​

sealed trait IO[A] {

  def flatMap[B](f: A => IO[B]): IO[B] = FlatMap(this, f)
}

final case class FlatMap[A, B](ioa: IO[A], f: A => IO[B])
  extends IO[B]

So, are we done, NOW?

IO.readLine
  .flatMap { line => IO.writeLine(line) }
  .flatMap { _ => IO.writeLine("said Echo") }
  .flatMap { _ => /* I want to return 2 here */ ??? }

I guess we need the third variant of IO

final case class Pure[A](a: A)
  extends IO[A]

object IO {

  def pure(a: A): IO[A] = Pure(a)

  // ...
}

Uff!

val sth: IO[Int] = IO.readLine
  .flatMap { line => IO.writeLine(line) }
  .flatMap { _ => IO.writeLine("said Echo") }
  .flatMap { _ => IO.pure(2) }

Bonus!

sealed trait IO[A] {

  def flatMap[B](f: A => IO[B]): IO[B] = FlatMap(this, f)
  def map[B](f: A => B): IO[B] = flatMap { a => IO.pure(f(b)) }
}

Questions?

Audience at this point

Thank you!

kubuszok.com

MateuszKubuszok

MateuszKubuszok