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

Functional Reactive Programming: A Video Game and Piece of CRUD

Functional Reactive Programming: A Video Game and Piece of CRUD

Functional Reactive Programming (FRP) is the best way to think about systems that have to deal with input.

If you disagree, you're wrong and I'll fight you.

This is a crash course to FRP.

But, we won't use a functional language.

• We will make a video game
◦ Space Invaders.
• We won't make a CRUD website
◦ But we'll talk about how we could

Scott Robinson

March 17, 2012
Tweet

More Decks by Scott Robinson

Other Decks in Programming

Transcript

  1. Whilst We Wait 1. Get LÖVE https://love2d.org/ 2. Code along

    git clone https://github.com/quad/invader.love.git
  2. Reactive Programming a = 1 b = 1 c =

    a + b print c 2 b = 2 print c
  3. function love.update(dt) if app.state ~= 'ready' then gvt.step(app, 'dt', dt)

    elseif app.state ~= 'stopped' then love.event.push('q') end end main.lua
  4. world.lua thing = {} function thing:_draw_list() return {{'rectangle', 'line', 10,

    10, 500, 500}} end __.extend(Screen, {thing}) await('key.escape')
  5. “Lift” • draw_list is a pure function • Same input,

    same output • _draw_list is a “lifted” function • Changed input, changed output
  6. invader.lua function constructor(n, sx, sy) ... col = n %

    Consts.swarm.columns row = math.floor(n / Consts.swarm.columns) _x = (col * (Consts.invader.side * Consts.invader.spacing.x)) + sx _y = (row * (Consts.invader.side * Consts.invader.spacing.y)) + sy
  7. invader.lua function draw_list(x, y) return {{ 'rectangle', 'line', x, y,

    Consts.invader.side, Consts.invader.side, }} end
  8. invader.lua function bounced(x) return x <= 0 or (x +

    Consts.invader.side) >= Consts.screen.width end return { _draw_list=L(draw_list)(_x, _y), _bounced=L(bounced)(_x), }
  9. swarm.lua function bounce() _v = _v() * -1 _y =

    _y() + Consts.invader.close end link(cond(_bounced), bounce)
  10. • Imperative exception to Functional graph traversal • Acts like

    a fork • “Reacts” to other Reactors • All reactive variables are Reactors The Reactor
  11. player.lua function constructor(ix, iy) ... _x = ix _y =

    iy return { _draw_list = L(draw_list)(_x, _y), }
  12. player.lua function draw_list(x, y) return {{ 'triangle', 'line', x, y,

    x + Consts.player.width, y + Consts.player.height, x - Consts.player.width, y + Consts.player.height, }} end
  13. player.lua _dir = 0 _x = ix _y = iy

    _v = L(v)(_dir, delay(_x)) _x = ix + S(_v)
  14. player.lua if x then if (x <= C.player.width and dir

    < 0) or (x >= C.screen.width - C.player.width and dir > 0) then return 0 else return Consts.player.speed * dir end end
  15. world.lua bullet = Bullet(500, 500, C.bullet.v) function shoot() bullet.shoot( player._x(),

    player._y() - C.bullet.height / 2 ) end link('key. ', shoot) link('key.up', shoot)
  16. bullet.lua function shoot(x, y) _x = x _y = y

    + S(v) end return { _draw_list = L(draw_list)(_x, _y), shoot = shoot, }
  17. Collision Detection • In pure implementions, handled “outside” as collision

    events. • In our hybrid, handled as a reactive state.
  18. invader.lua function colliding(abox, bbox) ax2, ay2 = abox.x + abox.width,

    abox.y + abox.height bx2, by2 = bbox.x + bbox.width, bbox.y + bbox.height return abox.x < bx2 and ax2 > bbox.x and abox.y < by2 and ay2 > bbox.y end
  19. invader.lua function draw_list(alive, x, y) if alive then ... else

    return {} end function bounced(alive, x) if alive then ... else return false end
  20. most productivity apps editors not useful? relational databases backup/restore filesystems

    (snapshot) git Redo Undo Event Based Event Based State Based State Based
  21. Bullet Swarm Invader Player key.left player_left player_move key.right player_right player_x

    shoot player_v player_draw_list bullet_shoot player_y bullet_y bullet_x key. key.up bullet_int_v bullet_box bullet_draw_list invader_hit screen swarm_int_v swarm_x swarm_draw_list invader_x invader_bounced swarm_bounced swarm_bounce swarm_v swarm_y invader_y invader_draw_list invader_box invader_die invader_alive player_dir player_int_v dt