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

Listen to Reason!

Listen to Reason!

Avatar for Huw Martin

Huw Martin

October 13, 2017

Other Decks in Programming

Transcript

  1. OCaml is actually less of a language and more of

    a toolset comprised of a syntax, an interpreter, a bytecode compiler, a debugger, a package manager (OPAM), and a native code compiler What’s so special about OCaml?
  2. This means that parts of the toolchain can be easily

    replaced Facebook can develop Reason as a syntax for OCaml Bloomberg can develop BuckScript as a compiler for OCaml to JavaScript And if something like WebAssembly gets super popular the compiler could just as easily be replaced with a different one for that What’s so special about OCaml?
  3. This means that parts of the toolchain can be easily

    replaced Facebook can develop Reason as a syntax for OCaml Bloomberg can develop BuckScript as a compiler for OCaml to JavaScript And if something like WebAssembly gets super popular the compiler could just as easily be replaced with a different one for that What’s so special about OCaml?
  4. This means that parts of the toolchain can be easily

    replaced Facebook can develop Reason as a syntax for OCaml Bloomberg can develop BuckleScript as a compiler for OCaml to JavaScript And if something like WebAssembly gets super popular the compiler could just as easily be replaced with a different one for that What’s so special about OCaml?
  5. This means that parts of the toolchain can be easily

    replaced Facebook can develop Reason as a syntax for OCaml Bloomberg can develop BuckleScript as a compiler for OCaml to JavaScript And if something like WebAssembly gets super popular the compiler could just as easily be replaced with a different one for that What’s so special about OCaml?
  6. With JS you sometimes need additional tooling Reason + BuckleScript

    can give you most of it What’s so special about Reason?
  7. Plain English helpful compiler error messages, inspired by Elm Facebook

    can develop Reason as a syntax for OCaml Bloomberg can develop BuckScript as a compiler for OCaml to JavaScript And if something like WebAssembly gets super popular the compiler could just as easily be replaced with a different one for that What’s so special about Reason?
  8. Plain English helpful compiler error messages, inspired by Elm Opinionated

    code formatting and linting on save with refmt Compiles to human-readable JS with does dead- code elimination Typing built in What’s so special about Reason?
  9. Code formatting with refmt On save it will turn this:

    let peek cat => switch (Random.bool ()) { | true => {lives: cat.lives - 1} | false => cat }; Into this: let peek cat => Random.bool () ? {lives: cat.lives - 1} : cat
  10. Plain English helpful compiler error messages, inspired by Elm Opinionated

    code formatting and linting on save with refmt Compiles to human-readable JS with dead-code elimination Typing built in What’s so special about Reason?
  11. Plain English helpful compiler error messages, inspired by Elm Opinionated

    code formatting and linting on save with refmt Compiles to human-readable JS with dead-code elimination Typing built in What’s so special about Reason?
  12. Disclaimer: I copied the main premise and code examples of

    this part of the presentation from a fun talk by Patrick Stapfer (@ryyppy) at the ReasonML London meetup Full code for the provided example can be found at github.com/ryyppy/reason-lnd
  13. First Attempt (JS) <Tictactoe> const state = { board: [null,

    ..., null], progress: "turn", player: "x", }; Why could this be problematic? No specification of what types can occupy board, progress, or player. Who knows what could go in there ¯\_(ツ)_/¯
  14. First Attempt (JS) <Tictactoe> const state = { board: [null,

    ..., null], progress: "turn", player: "x", }; Why could this be problematic? No specification of what types can occupy board, progress, or player. Who knows what could go in there ¯\_(ツ)_/¯
  15. First Attempt (JS) <Tictactoe> const state = { board: [null,

    ..., null], progress: "turn", player: "x", }; Why could this be problematic? No specification of what types can occupy board, progress, or player. Who knows what could go in there ¯\_(ツ)_/¯
  16. We could add some types w/ Flow... type Token =

    "X" | "O" | "Empty"; type Board = Array<Token>; type Player = "X" | "O"; type Progress = "turn" | "win" | "draw"; type State = { board: Board, progress: Progress, player: Player | null, }; This is nicer in that it is self-documenting to an extent and limits some unwanted behaviours
  17. It also has some confusing design implications type Token =

    "X" | "O" | "Empty"; type Board = Array<Token>; type Player = "X" | "O"; type Progress = "turn" | "win" | "draw"; type State = { board: Board, progress: Progress, player: Player | null, }; This is nicer in that it is self-documenting to an extent and limits some unwanted behaviours. const state: State = { board: [...], progress: "win", player: null, };
  18. It also has some confusing design implications type Token =

    "X" | "O" | "Empty"; type Board = Array<Token>; type Player = "X" | "O"; type Progress = "turn" | "win" | "draw"; type State = { board: Board, progress: Progress, player: Player | null, }; This is nicer in that it is self-documenting to an extent and limits some unwanted behaviours. const state: State = { board: [...], progress: "win", player: null, }; Because progress and player are independent you *could* end up in the confusing state of a game which has been won by nobody
  19. We could refactor the Player and Progress relationship type Player

    = "X" | "O"; type Progress = 
 { type: "turn", player: Player } | { type: "win", player: Player } | { type: "draw" } type State = { board: Board, progress: Progress, player: Player | null, };
  20. Types in action (Flow) const progress: Progress = { type:

    “turn", player: “X" }; switch (progress.type) { case "turn": const {player} = progress; return `Player ${player}'s turn`; case "win": const {player} = progress; return `Player ${player} won`; };
  21. But again things could go wrong… const progress: Progress =

    { type: “turn", player: “X" }; switch (progress.type) { case "turn": const {player} = progress; return `Player ${player}'s turn`; case "winner": const {player} = progress; return `Player ${player} won`; }; no checks for exhaustiveness tpyos verbose syntax flow infer is brittle progress = typeof Object
  22. So lets try designing the state in Reason instead type

    token = | X | O | Empty type board = ... type player = | X | O type progress = | Turn player | Win player 
 | Draw type state = { board: board progress: progress, };
  23. Types in action (Reason) let progress = Turn X; switch

    (progress) { | Turn p => "Player" ^ (p_to_str p) ^ "'s turn" | Win p => "Player" ^ (p_to_str p) ^ "won" | Draw => "It's a draw!" }; Compared to: switch (progress.type) { case "turn": const {player} = progress; return `Player ${player}'s turn`; case "win": const {player} = progress; return `Player ${player} won`; };
  24. What about the Board? With Reason it is still possible

    to run into some of the same issues as with JS: type board = list token let ok: board = [Empty, Empty,... , Empty] (9) When compared to JS: type Board = Array<Token>; Both leave the door open to potentially unsafe code, e.g. let derp: board = [Empty] You would probably need to write lots of additional tests to protect against this
  25. Better Board type row = (token, token, token) type board

    = (row, row, row) let r1: row = ( Empty, Empty, Empty) /* okay */ let r2: row = (Empty, X) /* type check fail */ let r3: row = (Empty, X, X, X) /* type check fail */ + Type safe with no surprises + "Less tests" to write - More verbose (but dead simple) code
  26. Helper types type columnId = | C1 | C2 |

    C3 type columnRow = | R1 | R2 | R3
  27. This lets you easily get a token from the board

    by specifying the column and row getToken :: board -> rowId -> colId -> token
  28. So what are the main characteristics of Reason code? More

    Rigid Design
 More KISS than DRY
 Forces edge-cases to be handled Functional but permissive
  29. Probably not yet.. Very immature Small ecosystem New community But

    when Facebook put their mind to something…
  30. Stuff to read and watch with your Messenger.com Now 50%

    Converted to Reason Brandon Dail: Critical ReasonML’ing Sean Grove: The Age of Reason(ML) A ReasonReact ToDo Tutorial Reason TicTacToe ReasonTools