$30 off During Our Annual Pro Sale. View Details »

Building Snake using Streams

Building Snake using Streams

This talk is an introduction to streams. You will learn how stream-based programming can be used to implement web frontend of the classic game: Snake.

Building dynamic applications using imperative approach tends to create lots of unmaintainable code. Stream-based programming tries to solve this problem by introducing fully declarative way of defining application logic. While using streams, you will focus on WHAT needs to be done, not HOW and WHEN. I will go through every piece of code that was used to build the game. That is about 100 lines of ES 2015 code contained within two React components.

Michał Płachta

March 19, 2016
Tweet

More Decks by Michał Płachta

Other Decks in Programming

Transcript

  1. meet.js summit / 19.03.2016 @miciek
    Building Snake using Streams
    Michał
    Płachta

    View Slide

  2. meet.js summit / 19.03.2016 @miciek
    Streams?
    ● application logic
    ● data transformations
    ● unbounded collections
    ● no time
    ● declarative

    View Slide

  3. meet.js summit / 19.03.2016 @miciek
    What you will learn?
    how frontend web app written in
    streams looks like

    View Slide

  4. meet.js summit / 19.03.2016 @miciek
    Meet Snake & Fruit
    Snake
    Fruit

    View Slide

  5. meet.js summit / 19.03.2016 @miciek
    Our First Stream: “Ticks” stream

    View Slide

  6. meet.js summit / 19.03.2016 @miciek
    “Directions” stream

    View Slide

  7. meet.js summit / 19.03.2016 @miciek
    “Snake’s Head Positions” stream

    View Slide

  8. meet.js summit / 19.03.2016 @miciek
    Stream operators: map & scan
    stream.map(f)
    ● transforms values from
    stream using function f
    ● returns a new stream
    with transformed values
    stream.scan(init, f)
    ● accumulates values
    from stream using
    function f
    ○ f(acc,val) =>
    new_acc
    ● returns a new stream
    that outputs
    accumulator on each
    new value

    View Slide

  9. meet.js summit / 19.03.2016 @miciek
    Once again: the code

    View Slide

  10. meet.js summit / 19.03.2016 @miciek
    Displaying values from the stream

    View Slide

  11. meet.js summit / 19.03.2016 @miciek
    Streams are reusable

    View Slide

  12. meet.js summit / 19.03.2016 @miciek
    Streams & Operators are lazy
    No elements
    =
    I don’t do
    anything

    View Slide

  13. meet.js summit / 19.03.2016 @miciek
    “Key presses” stream

    View Slide

  14. meet.js summit / 19.03.2016 @miciek
    “Left Key Presses” stream

    View Slide

  15. meet.js summit / 19.03.2016 @miciek
    “Right Key Presses” stream

    View Slide

  16. meet.js summit / 19.03.2016 @miciek
    Stream operators: filter
    stream.filter(p)
    ● checks each value from
    stream against the
    predicate passed as p
    ● returns a new stream
    that outputs only values
    that satisfy condition p
    Already used:
    ● map(f)
    ● scan(init, f(acc, val))

    View Slide

  17. meet.js summit / 19.03.2016 @miciek
    “Left Rotations” stream

    View Slide

  18. meet.js summit / 19.03.2016 @miciek
    “Right Rotations” stream

    View Slide

  19. meet.js summit / 19.03.2016 @miciek
    “Actions” stream

    View Slide

  20. meet.js summit / 19.03.2016 @miciek
    Stream operators: merge
    stream.merge(stream2)
    ● stream is merged with
    stream2
    ● returns a new stream that
    outputs values from both
    stream and stream2 as
    they appear
    Already used:
    ● map(f)
    ● scan(init, f(acc, val))
    ● filter(p)

    View Slide

  21. meet.js summit / 19.03.2016 @miciek
    Recap: Current “Directions” stream

    View Slide

  22. meet.js summit / 19.03.2016 @miciek
    “Directions” stream based on user input

    View Slide

  23. meet.js summit / 19.03.2016 @miciek
    “Directions” stream: Better, but no timing!
    vs

    View Slide

  24. meet.js summit / 19.03.2016 @miciek
    Stream operators: sampledBy
    stream.sampledBy(stream2)
    ● last value from stream is
    taken when any value
    appears in stream2
    ● returns a new stream that
    outputs values from
    stream sampled by values
    from stream2
    Already used:
    ● map(f)
    ● scan(init, f(acc, val))
    ● filter(p)
    ● merge(stream2)

    View Slide

  25. meet.js summit / 19.03.2016 @miciek
    “Directions” stream: user input & timing

    View Slide

  26. meet.js summit / 19.03.2016 @miciek
    “Snake Head Positions”: no change needed

    View Slide

  27. meet.js summit / 19.03.2016 @miciek
    User moves the snake: the code

    View Slide

  28. meet.js summit / 19.03.2016 @miciek
    Current implementation
    10 streams
    ● “ticks”
    ● “key presses”
    ● “left key presses”
    ● “right key presses”
    ● “left rotations”
    ● “right rotations”
    ● “actions”
    ● “direction changes”
    ● “directions”
    ● “snake head positions”
    + map, scan, filter, merge &
    sampledBy

    View Slide

  29. meet.js summit / 19.03.2016 @miciek
    Stream operators: slidingWindow
    stream.slidingWindow(n)
    ● aggregate last n values
    ● returns a new stream that
    outputs arrays of last n
    values from the stream
    ● can be implemented using
    scan
    Already used:
    ● map(f)
    ● scan(init, f(acc, val))
    ● filter(p)
    ● merge(stream2)
    ● sampledBy(stream2)

    View Slide

  30. meet.js summit / 19.03.2016 @miciek
    “Snakes” stream

    View Slide

  31. meet.js summit / 19.03.2016 @miciek
    Quiz: Eating a fruit?
    6 operators
    ● map(f)
    ● scan(init, f(acc, val))
    ● filter(p)
    ● merge(stream2)
    ● sampledBy(stream2)
    ● slidingWindow(n)
    WHICH STREAMS AND OPERATORS
    SHOULD WE REUSE TO
    IMPLEMENT “EATING A FRUIT”
    FUNCTIONALITY?
    11 streams
    ● “ticks”
    ● “key presses”
    ● “left key presses”
    ● “right key presses”
    ● “left rotations”
    ● “right rotations”
    ● “actions”
    ● “direction changes”
    ● “directions”
    ● “snake head positions”
    ● “snakes”

    View Slide

  32. meet.js summit / 19.03.2016 @miciek
    “Fruit eaten events” stream

    View Slide

  33. meet.js summit / 19.03.2016 @miciek
    Demo Time!

    View Slide

  34. KSUG / Kraków / 29.02.2016
    @miciek
    Architecture: 11 streams, 2 ins & 2 outs

    View Slide

  35. meet.js summit / 19.03.2016 @miciek
    Links
    github.com/miciek/web-snake-react-bacon Client Side Code
    rxmarbles.com/ Play with streams and operators!
    baconjs.github.io/ BaconJS - streams in JavaScript
    krakow.meetjs.pl/160112/ - Snake Live Coding talk
    And for the brave ones:
    github.com/miciek/snake-multiplayer-akka-streams Server Side Code

    View Slide

  36. meet.js summit / 19.03.2016 @miciek
    One more thing...
    Streams (Bacon.js, RxJS)
    +
    Virtual DOM (React.js)
    +
    Types (TypeScript, Flow)
    =
    Sane Frontend Programming

    View Slide

  37. meet.js summit / 19.03.2016 @miciek
    One more thing...
    Streams
    +
    Virtual DOM
    +
    Types
    =
    Elm .

    View Slide

  38. meet.js summit / 19.03.2016 @miciek
    Building Snake using Streams
    Michał Płachta
    www.michalplachta.com
    THANK YOU!

    View Slide