SlideShare a Scribd company logo
1 of 26
Download to read offline
MVC meets Monads
A functional-based design for a classic architectural pattern
Gianluca Aguzzi
Programming And Development Paradigms (PPS)
Deparment of Computer Science and Engineering (DISI)
ALMA MATER STUDIORUM–Università di Bologna, Cesena, Italy
September 1, 2021
It is all about composition [Mil19]
 Humans tend to divide complex problems in multiple pieces
 Then, solve each piece
 Finally compose all solutions to solve the initial problem
 Functional programming is a good way to compose different solutions :)
G.Aguzzi 1/25
Lecture goals
 Show an end-to-end functional application
 Leverage some well-consolidated functional libraries
 Understand limitations (if any) and the improvements
G.Aguzzi 2/25
Target application: Tic Tac Toe
Repository W
G.Aguzzi 3/25
OOP Design
Everything is an object
 Clear interface
 Incapsulated state
 Side effect as methods call
G.Aguzzi 4/25
Model
Core logic
 Main data to describe model entities (e.g. players?)
 Main methods to describe the game logic
1 /* two players (X, O) */
2 enum Player {
3 X, O, None; //Or? Optional?
4 }
5 /* a board 3x3 */
6 interface TicTacToe {
7 Player get(int X, int Y);
8 TicTacToe (or void??) update(int x, int y, Player p);
9 boolean isOver;
10 Player getTurn;
11 }
G.Aguzzi 5/25
View
Representation and IO boundary
 Describes what type of data it can consume (for rendering porpuse)
 Catches how to handle user’s inputs
 Ideally, the View could be totally decoupled from the Model
1 //a la' view model
2 interface ViewBoard {
3 ListString getRow(int row);
4 ListListString getAllBoard();
5 }
6 interface View extends ClickCellSource {
7 void render(ViewBoard board);
8 void winner(String player);
9 }
G.Aguzzi 6/25
View
Desing pattern
 the Input handler is usually solved exploiting the Observer [Gam95] pattern (also
called Listener).
1 public interface ClickCellSource {
2 void attach(Observer observer);
3 interface Observer {
4 void notify(int X, int Y);
5 }
6 }
G.Aguzzi 7/25
Controller
Goals
 Coordinates the interation between View and Model worlds
 Handles concurrency
 Adapts data
1 public interface Game extends ClickCellSource.Observer {
2 void start();
3 }
4
5 public class TicTacToeGame implements Game {
6 private final TicTacToe ticTacToe;
7 private final TicTacToeView ticTacToeView;
8
9 public static TicTacToeGame playWith(
10 final TicTacToe ticTacToe,
11 final TicTacToeView ticTacToeView) {...}
12 ....
G.Aguzzi 8/25
Putting all together
1 public static void main(String[] args) {
2 final TicTacToeView view = SwingView.createAndShow(800, 600);
3 final TicTacToe model = TicTacToeFactory.startX();
4 final Game game = TicTacToeGame.playWith(model, view);
5 game.start();
6 }
Clean enough, isn’t it?
What do you think?
 Try to rethink the design phase using functional abstractions
 (Monads? Functions? Algebraic Data Type?)
 Let’s go to the functional side :)
G.Aguzzi 9/25
Libraries
Cats W [Wel17]
provides abstractions for functional programming in the Scala
programming language.
Monix W
high-performance Scala / Scala.js library for composing asynchronous,
event-based programs.
G.Aguzzi 10/25
Task
Definition
Task represents a specification for a possibly lazy or asynchronous
computation, which when executed will produce a data as a result, along
with possible side-effects.
1 trait Task[+A] {
2 final def flatMap[B](f: A = Task[B]): Task[B] = ...
3 final def map[B](f : A = B): Task[B] = ...
4 //some interesting extesions
5 def memoize: Task[A] = ...
6 }
7 object Task {
8 def pure[A](a : A) : Task[A]
9 def defer[A](a : Task[A]) : Task[A]
10 }
What does it refer you to?
G.Aguzzi 11/25
A little taste
1 def someComputation(data : Long) : Task[Long] = Task.pure(data * 1000)
2
3 def log(value : String) : Task[Unit] = Task { println(value) }
4
5 val main = for {
6 data - someComputation(4)
7 _ - log(scomputations ends with value $data)
8 } yield (data)
9
10 main.runToFuture
Fiddle W
G.Aguzzi 12/25
Observable
Definition
A data type for modelling and processing asynchronous and reactive
streaming of events with non-blocking back-pressure.
Functional Reactive Programming [Has20] [Bla16]
 The program is expressed as a reaction to its inputs, or as a flow of data.
 We can use Observable to implement it
 Out of this talk, if you are interested, Conal Elliot W proposes a lot of materials
about this topic.
G.Aguzzi 13/25
An example with Scala.js :)
1 val textInput = input(placeholder := write text here).render
2 //unsafe boundary
3 val subject = PublishSubject[String]()
4 textInput.oninput = _ = subject.onNext(textInput.value)
5 val result = p.render
6 Fiddle.print(div(textInput), result)
7 //safe part
8 val inputStream = subject.share //API of the model
9 val computation = for {
10 text - inputStream
11 _ - Observable.pure(result.innerText = text)
12 } yield()
13
14 computation.foreachL(a = a).runToFuture
Fiddle W
G.Aguzzi 14/25
MVC + Functional, Intuition
 Model is described using Algebraic Data Type and operations (in a separated
module)
 View is modelled using monadic abstraction to wrap side effects
 Controller coordinates Model and View without introducing other side effects and
using a monadic manipulation (e.g. via flatmap)
Applied in our case
 Observable describes the user’s inputs flow
 Other computations (e.g. lazy and with side effects) are wrapped with Task
 Let’s start again :) (using Scala)
G.Aguzzi 15/25
Model
Domain Data
 Immutable data structures, operations can be described in a separated module
 We can enhance ADT with type classes
1 sealed trait TicTacToe {
2 def board: Map[Position, Player]
3 }
4 object TicTacToe {
5 val defaultSize: Int = 3
6 type Position = (Int, Int) //type aliases improve readability
7 case class InProgress(turn: Player, board: Map[Position, Player]) extends
TicTacToe
8 case class End(winner: Player, board: Map[Position, Player]) extends
TicTacToe
9 sealed trait Player {
10 def other: Player = ...
11 }
12 case object X extends Player
13 case object O extends Player
14 }
G.Aguzzi 16/25
Model
Operations
 Behaviour is described in terms of a function that evolves into a TicTacToe
instance
 Other ideas? State monad?
1 object TicTacToeOps {
2 def advanceWith(ticTacToe: TicTacToe, hit: Position): TicTacToe = {
3 val updateGame = for {
4 _ - rightPosition(ticTacToe, hit)
5 } yield updateBoard(ticTacToe, hit)
6 updateGame.getOrElse(ticTacToe)
7 }
8 def rightPosition(
9 ticTacToe: TicTacToe,
10 position: Position): Option[TicTacToe] = ....
11 def updateBoard(
12 ticTacToe: TicTacToe,
13 position: Position): TicTacToe = ...
14 ...
15 }
G.Aguzzi 17/25
View
Input-Output management
 IO is something outside of the model
 Boundary wraps something outside the control of the domain logic (e.g. GUI,
Console, Socket)
 Boundary, conceptually, can be defined as independent from a specific model data
(and input data)
 There are any problems with this solution?
1 trait Boundary[-Model, +Input] { //why generic?
2 def init(): Task[Unit] = Task.pure {}
3
4 def input: Observable[Input]
5
6 def consume(model: Model): Task[Unit]
7 }
G.Aguzzi 18/25
Controller
Application strucutres
 The application flow could be either reactive or proactive
 When it is reactive, the Controller updates the Model only when a new input occurs
 When it is proactive, the Controller updates the Model independently from the
input flow
Intuition
 Controller is a module (object) that exposes two function, i.e. reactive and
proactive
 Both functions, return a Task (i.e. wrap a computation)
Can we build it independently from Model and View?
 We only need a function accepting an Input (I) and evolving the Model (M)
returning a Task[M] (why?).
 An initial Model
 A boundary used for our application
G.Aguzzi 19/25
Controller, Structure
1 type UpdateFn[Model, Input] = (Model, Long, Seq[Input]) = Task[Model]
2
3 object Controller {
4
5 case class ProactiveConfig(timeTarget: FiniteDuration = 33.millis,
bufferSize: Int = 5)
6
7 def reactive[M, I](
8 boundary: Boundary[M, I],
9 model: M,
10 updateLogic: UpdateFn[M, I]): Task[Unit] = ....
11
12 def proactive[M, I](
13 boundary: Boundary[M, I],
14 model: M,
15 updateLogic: UpdateFn[M, I],
16 config: ProactiveConfig
17 ): Task[Unit] = ...
18
19 }
G.Aguzzi 20/25
View, Implementation
1 class View(width: Int = 800, height: Int = 600) extends Boundary[
TicTacToe, Hit] {
2 ....
3 override lazy val input: Observable[Hit] = Observable
4 .fromIterable(cells)
5 .map(liftToObservable)
6 .merge
7
8 override def consume(model: TicTacToe): Task[Unit] = {
9 for {
10 frame - container.asyncBoundary(swingScheduler) //go to AWT Thread
, todo it is a view task or controller task?
11 panel - board
12 _ - io(panel.removeAll())
13 _ - renderButtons(panel, model.board)
14 _ - renderVictory(model)
15 _ - io(frame.repaint()) //force repaint
16 _ - io(frame.setVisible(true)) //force repaint
17 } yield ()
18 }
19 ...
20 }
G.Aguzzi 21/25
Application
1 object TicTacToeSafe extends TaskApp {
2 override def run(args: List[String]): Task[ExitCode] = {
3 val view: Boundary[TicTacToe, Hit] = new View()
4 //main logic
5 val gameLogic: UpdateFn[TicTacToe, Hit] = UpdateFn.timeIndependent {
6 case (world, inputs) = TicTacToeInputProcess(world, inputs)
7 }
8 val loop = Controller.reactive(view, InProgress(X, Map.empty),
gameLogic)
9 loop.map(_ = ExitCode.Success)
10 }
11 }
G.Aguzzi 22/25
Recap
 We can clearly isolate side effects using Monads (Task, Observable)
 Then we can arbitrarily compose them to build an imperative-like behavior
 Model is side-effect free
 The program built is referential transparent
 Concurrency is handled through Monads themself (via shift, Fiber, ...)
Final remark
“The IO monad does not make a
function pure. It just makes it obvi-
ous that it’s impure”
Martin Odersky
[Ale17]
G.Aguzzi 23/25
Discussion
 My effort consists in merging MVC concepts with monads/functional programming
 Have you found some impurities? Or some lacks?
 Do you prefer the OOP solution or the Functional solution? And why?
Possible lacks (you can try to solve them as exercise :D)
 Error handling?
 Concurrency fine-control? Parallelism?
 Pure monadic view (my interface exposes side effects, isn’t it?)
 Cleaner Controller (monad transform?)
 Other application domain
 Other GUI supports
G.Aguzzi 24/25
Bibliography (1/1)
[Ale17] Alvin Alexander. Functional programming, simplified : simple, step-by-step approach to
learning functional programming. Boulder, Colo: Alvin Alexander, 2017. ISBN:
1979788782.
[Bla16] Stephen Blackheath. Functional reactive programming. Shelter Island, NY: Manning
Publications Co, 2016. ISBN: 9781633430105.
[Gam95] Erich Gamma. Design patterns : elements of reusable object-oriented software. Reading,
Mass: Addison-Wesley, 1995. ISBN: 0201633612.
[Has20] HaskellWiki. Functional programming — HaskellWiki, [Online; accessed 31-May-2021].
2020. URL: https://wiki.haskell.org/index.php?title=Functional_
programmingoldid=63198.
[Mil19] Bartosz Milewski. Category theory for programmers. Bartosz Milewski, 2019. ISBN:
9780464243878.
[Wel17] Gurnell Welsh. Scala with Cats. Bartosz Milewski, 2017.
G.Aguzzi 25/25

More Related Content

What's hot

Lec 10 10_sept [compatibility mode]
Lec 10 10_sept [compatibility mode]Lec 10 10_sept [compatibility mode]
Lec 10 10_sept [compatibility mode]
Palak Sanghani
 
JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES
Aditya Shah
 

What's hot (20)

Container adapters
Container adaptersContainer adapters
Container adapters
 
Lec 10 10_sept [compatibility mode]
Lec 10 10_sept [compatibility mode]Lec 10 10_sept [compatibility mode]
Lec 10 10_sept [compatibility mode]
 
2014 computer science_question_paper
2014 computer science_question_paper2014 computer science_question_paper
2014 computer science_question_paper
 
.net progrmming part2
.net progrmming part2.net progrmming part2
.net progrmming part2
 
Gentle Introduction to Functional Programming
Gentle Introduction to Functional ProgrammingGentle Introduction to Functional Programming
Gentle Introduction to Functional Programming
 
JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES
 
C#
C#C#
C#
 
Pattern printing programs
Pattern printing programsPattern printing programs
Pattern printing programs
 
2621008 - C++ 3
2621008 -  C++ 32621008 -  C++ 3
2621008 - C++ 3
 
Static and const members
Static and const membersStatic and const members
Static and const members
 
Drawing Figures
Drawing FiguresDrawing Figures
Drawing Figures
 
C++ TUTORIAL 10
C++ TUTORIAL 10C++ TUTORIAL 10
C++ TUTORIAL 10
 
Berlin meetup
Berlin meetupBerlin meetup
Berlin meetup
 
C++ TUTORIAL 1
C++ TUTORIAL 1C++ TUTORIAL 1
C++ TUTORIAL 1
 
Applications
ApplicationsApplications
Applications
 
Graphics in C++
Graphics in C++Graphics in C++
Graphics in C++
 
C # (2)
C # (2)C # (2)
C # (2)
 
Polymorphism
PolymorphismPolymorphism
Polymorphism
 
Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)Data Structure in C (Lab Programs)
Data Structure in C (Lab Programs)
 
54602399 c-examples-51-to-108-programe-ee01083101
54602399 c-examples-51-to-108-programe-ee0108310154602399 c-examples-51-to-108-programe-ee01083101
54602399 c-examples-51-to-108-programe-ee01083101
 

Similar to MVC meets Monad

Similar to MVC meets Monad (20)

Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to Griffon
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
Android basic 3 Dialogs
Android basic 3 DialogsAndroid basic 3 Dialogs
Android basic 3 Dialogs
 
從零開始學 Android
從零開始學 Android從零開始學 Android
從零開始學 Android
 
Informatics Practices (new) solution CBSE 2021, Compartment, improvement ex...
Informatics Practices (new) solution CBSE  2021, Compartment,  improvement ex...Informatics Practices (new) solution CBSE  2021, Compartment,  improvement ex...
Informatics Practices (new) solution CBSE 2021, Compartment, improvement ex...
 
PerfUG - Disruptor at ABC Arbitrage - March 2018
PerfUG - Disruptor at ABC Arbitrage - March 2018PerfUG - Disruptor at ABC Arbitrage - March 2018
PerfUG - Disruptor at ABC Arbitrage - March 2018
 
C#, What Is Next?
C#, What Is Next?C#, What Is Next?
C#, What Is Next?
 
Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)
 
Lab Practices and Works Documentation / Report on Computer Graphics
Lab Practices and Works Documentation / Report on Computer GraphicsLab Practices and Works Documentation / Report on Computer Graphics
Lab Practices and Works Documentation / Report on Computer Graphics
 
L11cs2110sp13
L11cs2110sp13L11cs2110sp13
L11cs2110sp13
 
Control Structures: Part 2
Control Structures: Part 2Control Structures: Part 2
Control Structures: Part 2
 
2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2
 
How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)
 
Using Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side EffectsUsing Redux-Saga for Handling Side Effects
Using Redux-Saga for Handling Side Effects
 
JEDI Slides-Intro2-Chapter20-GUI Event Handling.pdf
JEDI Slides-Intro2-Chapter20-GUI Event Handling.pdfJEDI Slides-Intro2-Chapter20-GUI Event Handling.pdf
JEDI Slides-Intro2-Chapter20-GUI Event Handling.pdf
 
Javascript: repetita iuvant
Javascript: repetita iuvantJavascript: repetita iuvant
Javascript: repetita iuvant
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180The Ring programming language version 1.5.1 book - Part 7 of 180
The Ring programming language version 1.5.1 book - Part 7 of 180
 
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
Dicoding Developer Coaching #30: Android | Mengenal Macam-Macam Software Desi...
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 

More from Gianluca Aguzzi

eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...
eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...
eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...
Gianluca Aguzzi
 

More from Gianluca Aguzzi (7)

Scala(e) to the large. Concurrent programming in Scala and relevant Frameworks
Scala(e) to the large. Concurrent programming in Scala and relevant FrameworksScala(e) to the large. Concurrent programming in Scala and relevant Frameworks
Scala(e) to the large. Concurrent programming in Scala and relevant Frameworks
 
Towards Reinforcement Learning-based Aggregate Computing
Towards Reinforcement Learning-based Aggregate ComputingTowards Reinforcement Learning-based Aggregate Computing
Towards Reinforcement Learning-based Aggregate Computing
 
Scala: a Cross-Platform Language
Scala: a Cross-Platform LanguageScala: a Cross-Platform Language
Scala: a Cross-Platform Language
 
On Collective Reinforcement Learning
On Collective Reinforcement LearningOn Collective Reinforcement Learning
On Collective Reinforcement Learning
 
ScaFi-Web, A Web-Based application for Field-based Coordination
ScaFi-Web, A Web-Based application for Field-based CoordinationScaFi-Web, A Web-Based application for Field-based Coordination
ScaFi-Web, A Web-Based application for Field-based Coordination
 
eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...
eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...
eCAS 2021: Towards Pulverised Architectures for Collective Adaptive Systems t...
 
Doctoral Symposium ACSOS 2021: Research directions for Aggregate Computing wi...
Doctoral Symposium ACSOS 2021: Research directions for Aggregate Computing wi...Doctoral Symposium ACSOS 2021: Research directions for Aggregate Computing wi...
Doctoral Symposium ACSOS 2021: Research directions for Aggregate Computing wi...
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Recently uploaded (20)

Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 

MVC meets Monad

  • 1. MVC meets Monads A functional-based design for a classic architectural pattern Gianluca Aguzzi Programming And Development Paradigms (PPS) Deparment of Computer Science and Engineering (DISI) ALMA MATER STUDIORUM–Università di Bologna, Cesena, Italy September 1, 2021
  • 2. It is all about composition [Mil19] Humans tend to divide complex problems in multiple pieces Then, solve each piece Finally compose all solutions to solve the initial problem Functional programming is a good way to compose different solutions :) G.Aguzzi 1/25
  • 3. Lecture goals Show an end-to-end functional application Leverage some well-consolidated functional libraries Understand limitations (if any) and the improvements G.Aguzzi 2/25
  • 4. Target application: Tic Tac Toe Repository W G.Aguzzi 3/25
  • 5. OOP Design Everything is an object Clear interface Incapsulated state Side effect as methods call G.Aguzzi 4/25
  • 6. Model Core logic Main data to describe model entities (e.g. players?) Main methods to describe the game logic 1 /* two players (X, O) */ 2 enum Player { 3 X, O, None; //Or? Optional? 4 } 5 /* a board 3x3 */ 6 interface TicTacToe { 7 Player get(int X, int Y); 8 TicTacToe (or void??) update(int x, int y, Player p); 9 boolean isOver; 10 Player getTurn; 11 } G.Aguzzi 5/25
  • 7. View Representation and IO boundary Describes what type of data it can consume (for rendering porpuse) Catches how to handle user’s inputs Ideally, the View could be totally decoupled from the Model 1 //a la' view model 2 interface ViewBoard { 3 ListString getRow(int row); 4 ListListString getAllBoard(); 5 } 6 interface View extends ClickCellSource { 7 void render(ViewBoard board); 8 void winner(String player); 9 } G.Aguzzi 6/25
  • 8. View Desing pattern the Input handler is usually solved exploiting the Observer [Gam95] pattern (also called Listener). 1 public interface ClickCellSource { 2 void attach(Observer observer); 3 interface Observer { 4 void notify(int X, int Y); 5 } 6 } G.Aguzzi 7/25
  • 9. Controller Goals Coordinates the interation between View and Model worlds Handles concurrency Adapts data 1 public interface Game extends ClickCellSource.Observer { 2 void start(); 3 } 4 5 public class TicTacToeGame implements Game { 6 private final TicTacToe ticTacToe; 7 private final TicTacToeView ticTacToeView; 8 9 public static TicTacToeGame playWith( 10 final TicTacToe ticTacToe, 11 final TicTacToeView ticTacToeView) {...} 12 .... G.Aguzzi 8/25
  • 10. Putting all together 1 public static void main(String[] args) { 2 final TicTacToeView view = SwingView.createAndShow(800, 600); 3 final TicTacToe model = TicTacToeFactory.startX(); 4 final Game game = TicTacToeGame.playWith(model, view); 5 game.start(); 6 } Clean enough, isn’t it? What do you think? Try to rethink the design phase using functional abstractions (Monads? Functions? Algebraic Data Type?) Let’s go to the functional side :) G.Aguzzi 9/25
  • 11. Libraries Cats W [Wel17] provides abstractions for functional programming in the Scala programming language. Monix W high-performance Scala / Scala.js library for composing asynchronous, event-based programs. G.Aguzzi 10/25
  • 12. Task Definition Task represents a specification for a possibly lazy or asynchronous computation, which when executed will produce a data as a result, along with possible side-effects. 1 trait Task[+A] { 2 final def flatMap[B](f: A = Task[B]): Task[B] = ... 3 final def map[B](f : A = B): Task[B] = ... 4 //some interesting extesions 5 def memoize: Task[A] = ... 6 } 7 object Task { 8 def pure[A](a : A) : Task[A] 9 def defer[A](a : Task[A]) : Task[A] 10 } What does it refer you to? G.Aguzzi 11/25
  • 13. A little taste 1 def someComputation(data : Long) : Task[Long] = Task.pure(data * 1000) 2 3 def log(value : String) : Task[Unit] = Task { println(value) } 4 5 val main = for { 6 data - someComputation(4) 7 _ - log(scomputations ends with value $data) 8 } yield (data) 9 10 main.runToFuture Fiddle W G.Aguzzi 12/25
  • 14. Observable Definition A data type for modelling and processing asynchronous and reactive streaming of events with non-blocking back-pressure. Functional Reactive Programming [Has20] [Bla16] The program is expressed as a reaction to its inputs, or as a flow of data. We can use Observable to implement it Out of this talk, if you are interested, Conal Elliot W proposes a lot of materials about this topic. G.Aguzzi 13/25
  • 15. An example with Scala.js :) 1 val textInput = input(placeholder := write text here).render 2 //unsafe boundary 3 val subject = PublishSubject[String]() 4 textInput.oninput = _ = subject.onNext(textInput.value) 5 val result = p.render 6 Fiddle.print(div(textInput), result) 7 //safe part 8 val inputStream = subject.share //API of the model 9 val computation = for { 10 text - inputStream 11 _ - Observable.pure(result.innerText = text) 12 } yield() 13 14 computation.foreachL(a = a).runToFuture Fiddle W G.Aguzzi 14/25
  • 16. MVC + Functional, Intuition Model is described using Algebraic Data Type and operations (in a separated module) View is modelled using monadic abstraction to wrap side effects Controller coordinates Model and View without introducing other side effects and using a monadic manipulation (e.g. via flatmap) Applied in our case Observable describes the user’s inputs flow Other computations (e.g. lazy and with side effects) are wrapped with Task Let’s start again :) (using Scala) G.Aguzzi 15/25
  • 17. Model Domain Data Immutable data structures, operations can be described in a separated module We can enhance ADT with type classes 1 sealed trait TicTacToe { 2 def board: Map[Position, Player] 3 } 4 object TicTacToe { 5 val defaultSize: Int = 3 6 type Position = (Int, Int) //type aliases improve readability 7 case class InProgress(turn: Player, board: Map[Position, Player]) extends TicTacToe 8 case class End(winner: Player, board: Map[Position, Player]) extends TicTacToe 9 sealed trait Player { 10 def other: Player = ... 11 } 12 case object X extends Player 13 case object O extends Player 14 } G.Aguzzi 16/25
  • 18. Model Operations Behaviour is described in terms of a function that evolves into a TicTacToe instance Other ideas? State monad? 1 object TicTacToeOps { 2 def advanceWith(ticTacToe: TicTacToe, hit: Position): TicTacToe = { 3 val updateGame = for { 4 _ - rightPosition(ticTacToe, hit) 5 } yield updateBoard(ticTacToe, hit) 6 updateGame.getOrElse(ticTacToe) 7 } 8 def rightPosition( 9 ticTacToe: TicTacToe, 10 position: Position): Option[TicTacToe] = .... 11 def updateBoard( 12 ticTacToe: TicTacToe, 13 position: Position): TicTacToe = ... 14 ... 15 } G.Aguzzi 17/25
  • 19. View Input-Output management IO is something outside of the model Boundary wraps something outside the control of the domain logic (e.g. GUI, Console, Socket) Boundary, conceptually, can be defined as independent from a specific model data (and input data) There are any problems with this solution? 1 trait Boundary[-Model, +Input] { //why generic? 2 def init(): Task[Unit] = Task.pure {} 3 4 def input: Observable[Input] 5 6 def consume(model: Model): Task[Unit] 7 } G.Aguzzi 18/25
  • 20. Controller Application strucutres The application flow could be either reactive or proactive When it is reactive, the Controller updates the Model only when a new input occurs When it is proactive, the Controller updates the Model independently from the input flow Intuition Controller is a module (object) that exposes two function, i.e. reactive and proactive Both functions, return a Task (i.e. wrap a computation) Can we build it independently from Model and View? We only need a function accepting an Input (I) and evolving the Model (M) returning a Task[M] (why?). An initial Model A boundary used for our application G.Aguzzi 19/25
  • 21. Controller, Structure 1 type UpdateFn[Model, Input] = (Model, Long, Seq[Input]) = Task[Model] 2 3 object Controller { 4 5 case class ProactiveConfig(timeTarget: FiniteDuration = 33.millis, bufferSize: Int = 5) 6 7 def reactive[M, I]( 8 boundary: Boundary[M, I], 9 model: M, 10 updateLogic: UpdateFn[M, I]): Task[Unit] = .... 11 12 def proactive[M, I]( 13 boundary: Boundary[M, I], 14 model: M, 15 updateLogic: UpdateFn[M, I], 16 config: ProactiveConfig 17 ): Task[Unit] = ... 18 19 } G.Aguzzi 20/25
  • 22. View, Implementation 1 class View(width: Int = 800, height: Int = 600) extends Boundary[ TicTacToe, Hit] { 2 .... 3 override lazy val input: Observable[Hit] = Observable 4 .fromIterable(cells) 5 .map(liftToObservable) 6 .merge 7 8 override def consume(model: TicTacToe): Task[Unit] = { 9 for { 10 frame - container.asyncBoundary(swingScheduler) //go to AWT Thread , todo it is a view task or controller task? 11 panel - board 12 _ - io(panel.removeAll()) 13 _ - renderButtons(panel, model.board) 14 _ - renderVictory(model) 15 _ - io(frame.repaint()) //force repaint 16 _ - io(frame.setVisible(true)) //force repaint 17 } yield () 18 } 19 ... 20 } G.Aguzzi 21/25
  • 23. Application 1 object TicTacToeSafe extends TaskApp { 2 override def run(args: List[String]): Task[ExitCode] = { 3 val view: Boundary[TicTacToe, Hit] = new View() 4 //main logic 5 val gameLogic: UpdateFn[TicTacToe, Hit] = UpdateFn.timeIndependent { 6 case (world, inputs) = TicTacToeInputProcess(world, inputs) 7 } 8 val loop = Controller.reactive(view, InProgress(X, Map.empty), gameLogic) 9 loop.map(_ = ExitCode.Success) 10 } 11 } G.Aguzzi 22/25
  • 24. Recap We can clearly isolate side effects using Monads (Task, Observable) Then we can arbitrarily compose them to build an imperative-like behavior Model is side-effect free The program built is referential transparent Concurrency is handled through Monads themself (via shift, Fiber, ...) Final remark “The IO monad does not make a function pure. It just makes it obvi- ous that it’s impure” Martin Odersky [Ale17] G.Aguzzi 23/25
  • 25. Discussion My effort consists in merging MVC concepts with monads/functional programming Have you found some impurities? Or some lacks? Do you prefer the OOP solution or the Functional solution? And why? Possible lacks (you can try to solve them as exercise :D) Error handling? Concurrency fine-control? Parallelism? Pure monadic view (my interface exposes side effects, isn’t it?) Cleaner Controller (monad transform?) Other application domain Other GUI supports G.Aguzzi 24/25
  • 26. Bibliography (1/1) [Ale17] Alvin Alexander. Functional programming, simplified : simple, step-by-step approach to learning functional programming. Boulder, Colo: Alvin Alexander, 2017. ISBN: 1979788782. [Bla16] Stephen Blackheath. Functional reactive programming. Shelter Island, NY: Manning Publications Co, 2016. ISBN: 9781633430105. [Gam95] Erich Gamma. Design patterns : elements of reusable object-oriented software. Reading, Mass: Addison-Wesley, 1995. ISBN: 0201633612. [Has20] HaskellWiki. Functional programming — HaskellWiki, [Online; accessed 31-May-2021]. 2020. URL: https://wiki.haskell.org/index.php?title=Functional_ programmingoldid=63198. [Mil19] Bartosz Milewski. Category theory for programmers. Bartosz Milewski, 2019. ISBN: 9780464243878. [Wel17] Gurnell Welsh. Scala with Cats. Bartosz Milewski, 2017. G.Aguzzi 25/25