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

The Road to a Statically Typed Future Pt.2

The Road to a Statically Typed Future Pt.2

JavaScript's dynamic nature and rich and expressive syntax are strengths of the language, making it an approachable and beginner-friendly language to get started with. However, this same flexibility through dynamic typing and runtime evaluation increases the difficulty of debugging and makes it tough to confidently change existing code.

This talk will discuss Patrick's personal journey and experience on using existing type systems within and outside of the JavaScript ecosystem, specifically Flow and ReasonML, and demonstrate how they can improve your workflow.

Patrick will talk about general concepts of why we need type definitions, how types will influence API designs, the differences between static and runtime types and how we can bridge the gap between a statically compiled, type-safe language and the JavaScript ecosystem.

This presentation is based on Pt.1 of this presentation series... in Pt. 2 he will demo how types will translate from the Flow type checker to the ReasonML language by using a practical example.

Presented at:

- 14th of September 2017 (JavaZone - Oslo)
- 23rd of September 2017 (Frontend Connect - Warsaw)
- 30th of September 2017 (ReactAlicante)

Patrick Stapfer

September 14, 2017
Tweet

More Decks by Patrick Stapfer

Other Decks in Programming

Transcript

  1. View Slide

  2. View Slide

  3. https://github.com/amazeeio/lagoon

    View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. View Slide

  10. View Slide

  11. const toSiteHostStr = (obj) =>
    R.compose(
    R.ifElse(
    R.compose(
    // (val) => val.length > 1,
    R.lt(1),
    R.length
    ),
    R.join('.'),
    R.compose(R.always(''))
    ),
    R.values,
    R.pick(['serverIdentifier', 'serverInfrastructure'])
    )(obj);

    View Slide

  12. View Slide

  13. View Slide

  14. View Slide

  15. View Slide

  16. View Slide

  17. View Slide

  18. View Slide

  19. View Slide

  20. View Slide

  21. View Slide

  22. View Slide

  23. View Slide

  24. View Slide

  25. View Slide

  26. View Slide

  27. View Slide

  28. View Slide

  29. View Slide

  30. View Slide

  31. type State = {
    board: Board,
    progress: Progress,
    };
    type Token = "X" | "O" | "Empty";
    type Board = Array;
    type Player = "X" | "O";
    type Progress = 

    { type: "turn", player: Player }
    | { type: "win", player: Player }
    | { type: "draw" }

    View Slide

  32. Types in Action
    switch (game.type) {
    case "turn":
    const {player} = game;
    return `Player ${player}'s turn`;
    case "win":
    const {player} = game;
    return `Player ${player} won`;
    };
    const game: Game = { type: "turn", player: "X" };

    View Slide

  33. "Pattern Matching" in Flow
    switch (game.type) {
    case "turn":
    const {player} = game;
    return `Player ${player}'s turn`;
    case "winner":
    const {player} = game;
    return `Player ${player} won`;
    };
    switch is no expression game = objects
    flow infer is brittle
    typoooooos
    No checks for exhaustiveness
    verbose syntax

    View Slide

  34. Let's design the model in Reason!
    type ticTacToeState = {
    board: board
    progress: progress,
    };
    type token = | X | O | Empty
    type player = | X | O
    type progress = 

    | Turn player

    | Win player

    | Draw
    type board = (row, row, row)
    type row = (token, token, token)

    View Slide

  35. Model Types in Action (Reason)
    switch (game) {
    | Turn p => "Player" ^ (p_to_str p) ^ "'s turn"
    | Win p => "Player" ^ (p_to_str p) ^ "won"
    | Draw => "It's a draw!"
    };
    let game = Turn X;
    switch (game.type) {
    case "turn":
    const {player} = game;
    return `Player ${player}'s turn`;
    case "win":
    const {player} = game;
    return `Player ${player} won`;
    };

    View Slide

  36. let parseGameJsonExn text =>
    Js.Json.parseExn text
    |> (fun json =>
    Json.Decode.{
    board: field "board" (array (array string)) json,
    progress: field "progress" (array string) json
    })
    |> convertData;

    View Slide

  37. let convertData {board, progress} :ticTacToeState => {
    board: parseBoard board,
    progress: parseProgress progress
    };
    function convertData(obj: {
    board: Array,
    progress: Array
    }): TicTacToeState

    View Slide

  38. let fetchData () =>
    Js.Promise.(
    fetch "/load"
    |> then_ Response.text
    |> then_ (fun text =>
    try (parseGameJsonExn text |> resolve) {
    | ex => reject ex
    })
    );
    function fetchData (): Promise

    View Slide

  39. // src/ticTacToe.re
    open Game;
    type action =
    | PlayTurn selection
    | Restart;
    type state = ticTacToeState;
    let component = ReasonReact.reducerComponent "TicTacToe";
    let make ::board=? ::progress=? _children => {
    ...component,
    initialState: fun () => { ... },
    reducer: fun action state =>
    switch action {
    | PlayTurn s => ReasonReact.Update (playTurn state s)
    | Restart => ReasonReact.Update (initialState ())
    },
    render: fun {state, reduce} => { ... }
    };

    View Slide

  40. ...
    render: fun {state, reduce} =>


    rows=state.board
    handleSquareClick=(
    reduce (fun selection => PlayTurn selection)
    ) />

    (
    switch state.progress {
    | Turn p => renderCurrentPlayer p
    | Win p => renderWin p (reduce (fun _evt => Restart))
    | Draw => renderDraw (reduce (fun _evt => Restart))
    }
    )

    ...

    View Slide

  41. View Slide

  42. type props = {
    value: token,
    handleClick: ReactEventRe.Mouse.t => unit
    };
    let component = ReasonReact.statelessComponent "Square";
    let squareStyle =
    ReactDOMRe.Style.make width::"25px" fontSize::"100pt" ();
    let make ::value ::handleClick _children => {
    ...component,
    render: fun _self =>

    (
    switch value {
    | Cross => X
    | Circle => O
    | Empty =>
    }
    )

    };

    View Slide

  43. http://github.com/ryyppy/reason-lnd
    Source Code for TicTacToe
    App + Server:

    View Slide

  44. View Slide

  45. View Slide