Freestyle, Free & Tagless: Separation of Concerns on Steroids

Freestyle, Free & Tagless: Separation of Concerns on Steroids

You will learn how to cut your applications into isolated, independent pieces using Freestyle library with free monads or tagless final style. The session is based on a multiplayer, purely functional version of Prisoner’s Dillema.

Our applications frequently consist of business logic, communication, persistence, caches & logging. We always want to keep them apart and reason about each of them individually. However, this is very difficult to achieve in practice.

Enter free monad. It lets us decouple those concerns by dividing our program into algebras and interpreters. I will show you an application built on top of free monad in Scala & Cats. You will learn how to create pure & declarative DSLs, side-effecting interpreters and how to use them together. Then I will introduce Freestyle library and show how it makes the code more concise. At the end I will compare the free monad approach to another technique used to decouple concerns: final tagless.

6f6dc1b13fd3fe35d36db3adafcb0c8e?s=128

Michał Płachta

December 15, 2017
Tweet

Transcript

  1. 3.

    @miciek Intelligent Thinking It is, that one is willing to

    study in depth an aspect of one's subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. Portrait by Hamilton Richards - manuscripts of Edsger W. Dijkstra, University Texas at Austin, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=4204157 “
  2. 4.

    @miciek Separate All the Things! High Level Logic Business #1

    Business #2 Logging Metrics DB Access Low Level Logic High Level Logic Low Level Logic business concern technical concern
  3. 5.

    @miciek Separate All the Things! High Level Logic Business #1

    Business #2 Logging Metrics DB Access Low Level Logic High Level Logic Low Level Logic business concern technical concern knows about
  4. 6.

    @miciek No outgoing arrows = separated High Level Logic Business

    #1 Business #2 Logging Metrics DB Access Low Level Logic High Level Logic Low Level Logic
  5. 11.

    @miciek Journey Prisoner’s Dilemma 3 apps 15 overlapping concerns using

    Cats & Freestyle more Freestyle Tagless Final hardcore concern separation
  6. 18.

    @miciek Prisoner’s Dilemma GUILTY! GUILTY! 3 years 3 years ...

    ... 1 year 1 year GUILTY! ... FREE 3 years
  7. 19.

    @miciek Prisoner’s Dilemma GUILTY! GUILTY! 3 years 3 years ...

    ... 1 year 1 year GUILTY! ... FREE 3 years ... GUILTY! 3 years FREE
  8. 21.
  9. 22.

    @miciek Hot Seat Game Welcome to Hot Seat Game, Prisoner

    A! What's your name? > Adam Hello, Adam! Welcome to Hot Seat Game, Prisoner B! What's your name? > Jane Hello, Jane!
  10. 23.

    @miciek Hot Seat Game Welcome to Hot Seat Game, Prisoner

    A! What's your name? > Adam Hello, Adam! Welcome to Hot Seat Game, Prisoner B! What's your name? > Jane Hello, Jane! Adam, is Jane guilty? > n Your decision: Silence Jane, is Adam guilty? > n Your decision: Silence Verdict for Adam is 1 year Verdict for Jane is 1 year
  11. 28.

    @miciek Hot Seat Game Concerns Hot Seat Logic Computing Verdict

    Player Interaction Player Communication using Console business concern technical concern knows about
  12. 29.

    @miciek Hot Seat Game Concerns Hot Seat Logic Computing Verdict

    Player Interaction Player Communication using Console
  13. 30.

    @miciek Hot Seat Game Concerns Hot Seat Logic Computing Verdict

    Player Interaction Player Communication using Console Free[F, A]
  14. 40.

    @miciek Connecting the Dots Hot Seat Logic Computing Verdict Player

    Interaction Player Communication using Console pure function Free[Player, A] Player[A] ~> IO[A] Free[S, Unit]
  15. 50.

    @miciek Playing with a Bot Welcome to Single Player Game!

    What's your name? > Michal Hello, Michal! Michal, is WALL-E guilty? > n Your decision: Silence Verdict for Michal is 1 year Adding new features is adding more concerns!
  16. 51.

    @miciek Reusing Values Computing Verdict Player Interaction Player Communication using

    Console Unknown Opponent Logic Opponent Interaction #1 #2 #3 Bot Opponent
  17. 61.

    @miciek Workflow 1. Define operations 2. Create programs 3. Try

    to run them 4. Fix errors by implementing interpreters Player Interaction Unknown Opponent Unknown Opponent
  18. 62.

    @miciek Different Interpreter for Opponent? Computing Verdict Player Interaction Player

    Communication using Console Unknown Opponent Logic Opponent Interaction ? Bot Opponent
  19. 63.

    @miciek Remote Opponent Computing Verdict Player Interaction Player Communication using

    Console Unknown Opponent Logic Opponent Interaction Remote Opponent Bot Opponent
  20. 64.

    @miciek Meeting Remote Opponent Player A Player B RegisterAsWaiting GetWaitingPlayers

    JoinWaitingPlayer CheckIfOpponentJoined UnregisterWaiting found Player A found Player B
  21. 66.

    @miciek Matchmaking Programs Player A Player B waitForOpponent findOpponent RegisterAsWaiting

    GetWaitingPlayers JoinWaitingPlayer CheckIfOpponentJoined UnregisterWaiting
  22. 69.

    @miciek Remote Opponent Computing Verdict Player Interaction Player Communication using

    Console Unknown Opponent Logic Opponent Interaction Remote Opponent Bot Opponent
  23. 73.

    @miciek Workflow 1. Define operations 2. Create programs 3. Try

    to run them 4. Fix errors by implementing interpreters Player Interaction Unknown Opponent Unknown Opponent
  24. 74.

    @miciek Recap: Game with a Bot Unknown Opponent Logic Opponent

    Interaction Bot Opponent var state: Map ...
  25. 75.

    @miciek Interpreting into Free Unknown Opponent Logic Opponent Interaction Bot

    Opponent var state: Map ... Remote Opponent is interpreting into another Free program! Remote Opponent
  26. 83.

    @miciek 3 Game Modes = 15 Concerns + 31 Tests

    Computing Verdict Player Interaction Player Communication using Console Unknown Opponent Logic Opponent Interaction Remote Opponent Bot Opponent Decision Registry Matchmaking Matchmaking Server Decision Server Timing Hot Seat Logic EoW Thread Timing x3 Player Local Interaction
  27. 84.

    @miciek 3 Game Modes = 15 Concerns + 31 Tests

    Computing Verdict Player Interaction Player Communication using Console Unknown Opponent Logic Opponent Interaction Remote Opponent Bot Opponent Decision Registry Matchmaking Matchmaking Server Decision Server Timing Hot Seat Logic EoW Thread Timing x3 Player Local Interaction Thread.sleep println var
  28. 85.
  29. 89.
  30. 93.

    @miciek Course of Action ▪ Use Free directly using cats

    or scalaz ▪ Use Final Tagless directly ▪ When comfortable, start using freestyle ▪ Decide @tagless or @free per use case
  31. 94.

    @miciek @free or @tagless? @free @tagless program is data program

    is an expression plain values expressions parametrized by F[_] stack-safe stack-safe iff F[_] is stack-safe Remember: Mix and match your algebras using Freestyle! More here: https://softwaremill.com/free-tagless-compared-how-not-to-commit-to-monad-too-early/ Note that Freestyle gets rid of some problems mentioned there!