Functional and reactive u is gwt.create 2015

H
Functional and
Reactive UIs
Henri Muurimaa
SVP of Engineering, Vaadin
henri@vaadin.com @henrimuurimaa
Number of metal bands per capita
Functional
programming
Reactive
programming
Functional and reactive UI programming
A style of programming that
expresses computation as the
evaluation of mathematical
functions
Recursion
Lazy evaluation
Lambda expressions
Type theory
Monads
Referential
transparency
Currying
Entscheidungsproblem
Pattern matching
Tuples
Something practical?
Side effects?
State?
No
Bad
Okay…
Functional and reactive u is gwt.create 2015
What instead of how
val square = (number: Int) => number * number
Functional programming 101
val tenSquared = square(10)
val nums = List(1,2,3)
val squares = nums map square // List(1, 4, 9)
val evenNums = nums filter { _ % 2 == 0 } // List(2)
val letters = List("a", "b", "c")
val numbersWithLetters = squares zip letters // List((1,a), (4,b), (9,c))
Null checks
are a code smell
val presentNumber: Option[Int] = Some(10)
Dealing with absent
values on the type level
val absentNumber: Option[Int] = None
val wrappedNull: Option[Int] = Option(null) // None
Working with Option
case class User(name: String, id: Int)
trait UserRepository {
def findById(i: Int): Option[User]
}
val user = userRepository.findById(1) // Option[User]
if(user.isDefined) {
println("User name: " + user.get.name)
}
user foreach { u => println("User name: " + u.name) }
val nameOpt = user map { _.name } // Option[String]
val name = user map { _.name } getOrElse "No user found"
Player
Enemy
Illuminated
areaPlayer
sight
range
github.com/hezamu/DungeonGame
case class Cell(x: Int, y: Int) {
def +(other: Cell) = Cell(x + other.x, y + other.y)
}
class Dungeon {
var floors: Set[Cell] = Set()
var entities: Map[Entity, Cell] = Map()
def visibleIlluminatedCells = ???
}
Dungeon model
class Dungeon {
var floors: Set[Cell] = Set()
var entities: Map[Entity, Cell] = Map()
def playerOpt = entities.keys collect { case p: Player => p } headOption
def playerCellOpt = playerOpt map entities
def playerSightRange = playerOpt map { _.sightRange } getOrElse 0
def inPlayerSightRange(cell: Cell) = playerCellOpt map { playerPos =>
MapLogic.distance(playerPos, cell) <= playerSightRange
} getOrElse false
def visibleIlluminatedCells = {
val lightSources = entities map {
case (entity, cell) => (cell, entity.illuminationRadius)
}
val visibles = lightSources flatMap MapLogic.area filter inPlayerSightRange
floors intersect visibles.toSet
}
}
Functional summary
Option lets you get rid of NPEs forever
Use small functions with clear
responsibilities
Chaining functional operations is
practically a superpower
What is
Reactive
Programming?
int a = b + 1; =B1+1
Spot the difference?
Vaadin
ComboBox cities = new ComboBox();
Label selectedCity = new Label();
selectedCity.setPropertyDataSource(cities);
Tessell
void onInit() {
employee.name.set(name);
binder.bind(employee.name).to(textOf(view.employeeName()));
}
void someBusinessLogic() {
// only have to set the name
employee.name.set(newName);
}
Listening to events
is a code smell
val numbers = Observable.from(List(1, 2, 3))
numbers subscribe { n => println(n) }
Observables to the rescue
val squares = numbers map { num => num * num }
val letters = Observable.from(List("a", "b", "c"))
val numbersWithLetters = squares zip letters
RxVaadinwww.vaadin.com/blog/-/blogs/reactive-functional-ui-development-with-vaadin
val movesObserver = Vector(
up.clickEvents map { e => tryMove(Cell(0, -1)) },
down.clickEvents map { e => tryMove(Cell(0, 1)) },
left.clickEvents map { e => tryMove(Cell(-1, 0)) },
right.clickEvents map { e => tryMove(Cell(1, 0)) }
)
def tryMove(delta: Cell) = board.dungeon.playerPosition map { cell =>
cell + delta
} filter board.dungeon.canMoveTo
Observing player moves
// Emit a Option[Cell] every time player tries to move
val moveObserver = Observable from movesObserver flatten
// Map a legal destination cell to the set of visible cells after the move
val visibleCellsObserver = moveObserver collect { case Some(cell) =>
board.dungeon.playerOpt foreach { board.dungeon.put(_, cell) }
board.dungeon.visibleIlluminatedCells
}
// Subscribe the game board instance to the stream of legal moves.
// This will call board.onNext() with a set of visible cells whenever
// player performs a legal move.
visibleCellsObserver subscribe board
Handling legal moves
// Subscribe to the illegal move stream to show a notification every
// time player tries an illegal move.
moveObserver filter { _.isEmpty } subscribe { none =>
Notification.show("That direction is blocked", Notification.Type.Tray)
}
Handling illegal moves
Summary
These techniques are very powerful and
they can be learned gradually
Both functional and reactive techniques
are great with UIs
Functional puts FUN back in
programming!
Thank You!
github.com/hezamu
@henrimuurimaa
henri@vaadin.com
1 of 28

More Related Content

What's hot(20)

Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Hang Zhao995 views
Railway reservation systemRailway reservation system
Railway reservation system
Prashant Sharma2.9K views
Import javaImport java
Import java
heni2121128 views
Supstat nyc subwaySupstat nyc subway
Supstat nyc subway
Vivian S. Zhang1.5K views
Monogame Introduction (ENG)Monogame Introduction (ENG)
Monogame Introduction (ENG)
Aloïs Deniel383 views
Unit testUnit test
Unit test
David Xie501 views
Introduction to Java ProgrammingIntroduction to Java Programming
Introduction to Java Programming
Pokequesthero147 views
Sbaw090623Sbaw090623
Sbaw090623
Atsushi Tadokoro868 views
Flare3d jiglib.asFlare3d jiglib.as
Flare3d jiglib.as
Fabricio Goncalves219 views
Node meetup feb_20_12Node meetup feb_20_12
Node meetup feb_20_12
jafar104228 views
Utility Classes Are Killing UsUtility Classes Are Killing Us
Utility Classes Are Killing Us
Yegor Bugayenko612 views
Anomalies in X-Ray EngineAnomalies in X-Ray Engine
Anomalies in X-Ray Engine
PVS-Studio50 views
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2
Evgeny Borisov696 views

Similar to Functional and reactive u is gwt.create 2015

MonadologieMonadologie
Monadologieleague
3.6K views58 slides
Coding in StyleCoding in Style
Coding in Stylescalaconfjp
1.4K views59 slides

Similar to Functional and reactive u is gwt.create 2015(20)

MonadologieMonadologie
Monadologie
league3.6K views
Swift, via "swift-2048"Swift, via "swift-2048"
Swift, via "swift-2048"
Austin Zheng2K views
Coding in StyleCoding in Style
Coding in Style
scalaconfjp1.4K views
First-Class PatternsFirst-Class Patterns
First-Class Patterns
John De Goes3.2K views
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
league1.4K views
10. Recursion10. Recursion
10. Recursion
Intro C# Book21.3K views
Scala best practicesScala best practices
Scala best practices
Alexander Zaidel319 views
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
Christian Baranowski1.2K views
Introduction to Dependently Types: IdrisIntroduction to Dependently Types: Idris
Introduction to Dependently Types: Idris
Abdulsattar Mohammed389 views
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in Swift
Aleksandras Smirnovas3.4K views
Scala for curiousScala for curious
Scala for curious
Tim (dev-tim) Zadorozhniy514 views

Functional and reactive u is gwt.create 2015

  • 1. Functional and Reactive UIs Henri Muurimaa SVP of Engineering, Vaadin henri@vaadin.com @henrimuurimaa
  • 2. Number of metal bands per capita
  • 4. A style of programming that expresses computation as the evaluation of mathematical functions
  • 5. Recursion Lazy evaluation Lambda expressions Type theory Monads Referential transparency Currying Entscheidungsproblem Pattern matching Tuples
  • 10. val square = (number: Int) => number * number Functional programming 101 val tenSquared = square(10) val nums = List(1,2,3) val squares = nums map square // List(1, 4, 9) val evenNums = nums filter { _ % 2 == 0 } // List(2) val letters = List("a", "b", "c") val numbersWithLetters = squares zip letters // List((1,a), (4,b), (9,c))
  • 11. Null checks are a code smell
  • 12. val presentNumber: Option[Int] = Some(10) Dealing with absent values on the type level val absentNumber: Option[Int] = None val wrappedNull: Option[Int] = Option(null) // None
  • 13. Working with Option case class User(name: String, id: Int) trait UserRepository { def findById(i: Int): Option[User] } val user = userRepository.findById(1) // Option[User] if(user.isDefined) { println("User name: " + user.get.name) } user foreach { u => println("User name: " + u.name) } val nameOpt = user map { _.name } // Option[String] val name = user map { _.name } getOrElse "No user found"
  • 15. case class Cell(x: Int, y: Int) { def +(other: Cell) = Cell(x + other.x, y + other.y) } class Dungeon { var floors: Set[Cell] = Set() var entities: Map[Entity, Cell] = Map() def visibleIlluminatedCells = ??? } Dungeon model
  • 16. class Dungeon { var floors: Set[Cell] = Set() var entities: Map[Entity, Cell] = Map() def playerOpt = entities.keys collect { case p: Player => p } headOption def playerCellOpt = playerOpt map entities def playerSightRange = playerOpt map { _.sightRange } getOrElse 0 def inPlayerSightRange(cell: Cell) = playerCellOpt map { playerPos => MapLogic.distance(playerPos, cell) <= playerSightRange } getOrElse false def visibleIlluminatedCells = { val lightSources = entities map { case (entity, cell) => (cell, entity.illuminationRadius) } val visibles = lightSources flatMap MapLogic.area filter inPlayerSightRange floors intersect visibles.toSet } }
  • 17. Functional summary Option lets you get rid of NPEs forever Use small functions with clear responsibilities Chaining functional operations is practically a superpower
  • 19. int a = b + 1; =B1+1 Spot the difference?
  • 20. Vaadin ComboBox cities = new ComboBox(); Label selectedCity = new Label(); selectedCity.setPropertyDataSource(cities); Tessell void onInit() { employee.name.set(name); binder.bind(employee.name).to(textOf(view.employeeName())); } void someBusinessLogic() { // only have to set the name employee.name.set(newName); }
  • 21. Listening to events is a code smell
  • 22. val numbers = Observable.from(List(1, 2, 3)) numbers subscribe { n => println(n) } Observables to the rescue val squares = numbers map { num => num * num } val letters = Observable.from(List("a", "b", "c")) val numbersWithLetters = squares zip letters
  • 24. val movesObserver = Vector( up.clickEvents map { e => tryMove(Cell(0, -1)) }, down.clickEvents map { e => tryMove(Cell(0, 1)) }, left.clickEvents map { e => tryMove(Cell(-1, 0)) }, right.clickEvents map { e => tryMove(Cell(1, 0)) } ) def tryMove(delta: Cell) = board.dungeon.playerPosition map { cell => cell + delta } filter board.dungeon.canMoveTo Observing player moves // Emit a Option[Cell] every time player tries to move val moveObserver = Observable from movesObserver flatten
  • 25. // Map a legal destination cell to the set of visible cells after the move val visibleCellsObserver = moveObserver collect { case Some(cell) => board.dungeon.playerOpt foreach { board.dungeon.put(_, cell) } board.dungeon.visibleIlluminatedCells } // Subscribe the game board instance to the stream of legal moves. // This will call board.onNext() with a set of visible cells whenever // player performs a legal move. visibleCellsObserver subscribe board Handling legal moves
  • 26. // Subscribe to the illegal move stream to show a notification every // time player tries an illegal move. moveObserver filter { _.isEmpty } subscribe { none => Notification.show("That direction is blocked", Notification.Type.Tray) } Handling illegal moves
  • 27. Summary These techniques are very powerful and they can be learned gradually Both functional and reactive techniques are great with UIs Functional puts FUN back in programming!