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

2018 - React Chicago - ReasonReact - A Love Story

2018 - React Chicago - ReasonReact - A Love Story

When I first met ReactJS, it was love at first sight. We built beautiful UIs for years together with our firstborn, Redux. I felt like nothing would get between us. Not even when a younger, skinnier version came along (Preact). Life was good.

Everything changed when ReasonReact showed up on our block. I was curious, of course. Didn’t act on it, though. Why would I? We’d run into each other a lot since we shared the same circles. One day, the temptations got too strong. What was I thinking? Nothing about what I was doing felt right, at first. I was leaving a lot behind but for some weird reason, I knew I’d end up here anyway. I mean, it’s not like we’re splitting apart. React will still be there, but so will Reason...

I’m here to announce my love affair.

Peter Piekarczyk

June 27, 2018
Tweet

More Decks by Peter Piekarczyk

Other Decks in Technology

Transcript

  1. ReasonML - A Love Story
    Peter Piekarczyk
    @peterpme
    draftbit.com
    June 27, 2018

    View Slide

  2. Draftbit
    Build x-plat apps in
    minutes instead of months

    View Slide

  3. Life Before 2015
    Backbone
    Angular
    RequireJS
    jQuery
    Bower
    Gulp MVC
    CoffeeScript

    View Slide

  4. Life Before 2015
    lmao

    View Slide

  5. 2015 & Beyond
    Flowtype
    Eslint
    Babel
    Typescript
    Redux Yarn
    Prettier
    React
    Immutable

    View Slide

  6. ReasonML

    View Slide

  7. What is ReasonML
    • New language by the creator of React
    • Familiar JavaScript syntax on top of OCaml AST
    • Battle-tested language & ecosystem
    • Friendly compiler errors & warnings

    View Slide

  8. JavaScript as a statically typed,
    functional language with a super fast
    compiler & amazing error messages
    What is ReasonML

    View Slide

  9. If it compiles,
    it works.

    View Slide

  10. • Compiles 10x faster than Babel
    • Eliminates typical Javascript errors
    • Use it alongside your current JS apps
    • Compiles down to native binaries
    • Readable compiled JavaScript
    Why Consider Reason

    View Slide

  11. ReasonML Companies

    View Slide

  12. Messenger.com
    •Full rebuild (100s of files) is 2 seconds
    •Incremental builds are < 100ms
    •10 bugs for the whole year vs every week
    •Refactoring reduced to minutes instead of days

    View Slide

  13. Friendly Compiler Warnings

    View Slide

  14. Friendly Compiler Warnings

    View Slide

  15. Fast AF Compile Times
    Scala
    Kotlin
    TypeScript

    View Slide

  16. The compiled

    JavaScript is
    Readable

    View Slide

  17. let fizzbuzz = (i) !=>
    switch (i mod 3, i mod 5) {
    | (0, 0) !=> "FizzBuzz"
    | (0, _) !=> "Fizz"
    | (_, 0) !=> "Buzz"
    | _ !=> string_of_int(i)
    };

    View Slide

  18. function fizzbuzz(i) {
    var match = i % 3;
    var match$1 = i % 5;
    if (match !!!== 0) {
    if (match$1 !!!== 0) {
    return String(i);
    } else {
    return "Buzz";
    }
    } else if (match$1 !!!== 0) {
    return "Fizz";
    } else {
    return "FizzBuzz";
    }
    }

    View Slide

  19. let rec factorial = (n) !=>
    n !<= 0
    ? 1
    : n * factorial(n - 1);

    View Slide

  20. var Caml_int32 = require("stdlib/caml_int32");
    function factorial(n) {
    var match = n !<= 0;
    if (match) {
    return 1;
    } else {
    return Caml_int32.imul(n, factorial(n - 1 | 0));
    }
    }

    View Slide

  21. Faster than hand-
    written JavaScript

    View Slide

  22. let test = () !=> {
    let m = ref(IntMap.empty);
    let count = 1000000;
    for (i in 0 to count) {
    m !:= IntMap.add(i, i, m^);
    };
    for (i in 0 to count) {
    ignore(IntMap.find(i, m^));
    };
    };

    View Slide

  23. var Map = Immutable.Map;
    var m = new Map();
    var test = function() {
    var count = 1000000;
    for(var i = 0; i < count; !++i) {
    m = m.set(i, i);
    }
    for(var j = 0; j < count; !++j) {
    m.get(j);
    }
    }
    test();

    View Slide

  24. Fast AF Execution
    • ReasonML Immutable Map: 1186ms
    • ImmutableJS Map: 3415ms

    View Slide

  25. Optimized Tree Shaking
    • BuckleScript: 899 Bytes
    • Immutable JS: 55.3K Bytes

    View Slide

  26. How!?
    Everything happens at compile time
    Everything is built & organized to be fast & light

    View Slide

  27. Ocaml & Reason
    Same Semantics

    Different Syntax

    View Slide

  28. Compile Targets
    ReasonML syntax

    (.re, .rei)
    OCaml syntax

    (.ml, .mli)
    OCaml AST
    JavaScript
    Native Code
    Bytecode
    ocamlc ocamlopt BuckleScript
    reasonmlhub.com

    View Slide

  29. • Established Language (1996)
    • Used in high-performance apps
    • Facebook uses it for everything (Flow, Hack)
    • First version of React was in Standard ML
    Why OCaml

    View Slide

  30. • Babel became a popular thing
    • Bloomberg released BuckleScript
    • Jordan rewrote React in OCaml
    • Believed the world was ready
    ReasonML History

    View Slide

  31. • First versions of React were written in StandardML
    • Babel didn’t exist
    • Adoption would have been hard
    • ReactJS was born!
    React History

    View Slide

  32. Is ReasonML Ready?
    Ya

    View Slide

  33. Write safer & simpler code

    in OCaml or Reason

    that compiles to JavaScript
    BuckleScript

    View Slide

  34. BuckleScript Goals
    • Readable JavaScript output
    • Supports the current JS ecosystem
    • Compiles really fast

    View Slide

  35. Use any Javascript module
    Just write the bindings
    Bindings

    View Slide

  36. Bindings
    •bs-*
    •bs-react-native
    •bs-fetch
    •bs-moment

    View Slide

  37. Bindings
    type t;
    [@bs.get] external hairlineWidth : t !=> float =
    "hairlineWidth";
    let hairlineWidth = hairlineWidth(t);

    View Slide

  38. The hardest part
    Bindings

    View Slide

  39. Types
    • Can be inferred
    • Coverage is *always* 100%
    • Completely sound
    • Consume arguments like a function

    View Slide

  40. Types
    let friend = “Jeff”;
    let friend: string = “Jeff”;

    View Slide

  41. Types
    type intCoordinates = (int, int);
    type coordinates(‘a) = (‘a, ‘a);
    let intCoordinates = coordinates(int);
    let house: coordinates(float) = (0.12, -0.12);
    let house = (0.12, -0.12);

    View Slide

  42. Variants
    type myResponseVariant =
    | Yes
    | No
    | PrettyMuch;
    let areYouCrushingIt = Yes;
    this OR that OR that

    View Slide

  43. Pattern Matching
    let message =
    switch (areYouCrushingIt) {
    | No !=> "No worries. Keep going!"
    | Yes !=> "Great!"
    | PrettyMuch !=> "Nice!"
    };
    “Great!”

    View Slide

  44. Pattern Matching
    let message = “sup";
    let reply =
    switch (message) {
    | "Reason's pretty cool" !=> "Yep"
    | "good night" !=> "See ya!"
    | “hello" | "hey" !=> "hello to you too!"
    | _ !=> "Nice to meet you!"
    };
    “Nice to meet you!”

    View Slide

  45. Modules
    • Treated as mini files
    • Can include types & nested modules
    • Can be “opened” and “extended”

    View Slide

  46. Modules
    module School = {
    type profession = Teacher | Director;
    let person1 = Teacher;
    let getProfession = (person) !=>
    switch (person) {
    | Teacher !=> "A teacher"
    | Director !=> "A director"
    };
    };
    let anotherPerson: School.profession = School.Teacher;

    View Slide

  47. Module Opens
    open BsReactNative;
    StyleSheet.create(…)
    Global Open:
    Local Open:
    let styles =

    StyleSheet.create(
    Style.(…)

    View Slide

  48. • Write React components using Reason
    • Not a re-write, just the bindings
    • Safe & statically typed: it just works!
    ReasonReact

    View Slide

  49. Your First Component
    let component = ReasonReact.statelessComponent("Greeting");
    let make = (~name, _children) !=> {
    !!...component,
    render: (_self) !=>

    {ReasonReact.string("Hello " !++ name !++ “!")}
    !
    };

    View Slide

  50. Stateless Components
    let component = ReasonReact.statelessComponent("Greeting");

    View Slide

  51. Arguments
    let make = (~name, _children) !=> {
    !!...component,
    render: (_self) !=>

    {ReasonReact.string("Hello " !++ name !++ “!")}
    !
    };

    View Slide

  52. Arguments
    let make = (~name, _children) !=> {
    …ReasonReact.statelessComponent(“Greeting"),
    render: (_self) !=>

    {ReasonReact.string("Hello " !++ name !++ “!")}
    !
    };
    DO NOT DO THIS!!!

    View Slide

  53. Render
    render: (_self) !=>

    {ReasonReact.string("Hello " !++ name !++ “!")}
    !

    View Slide

  54. String to React Element
    {ReasonReact.string("Hello " !++ name !++ “!")}

    View Slide

  55. • npm install -g bs-platform
    • add bsconfig.json
    • bsb -make-world -clean-world
    Existing Project

    View Slide

  56. bsconfig.json
    {
    "name": “my-project”,
    "reason": {"react-jsx" : 2},
    "bsc-flags": ["-bs-super-errors"],
    "package-specs": [{"module": “commonjs", "in-source": true}],
    "suffix": ".bs.js",
    "namespace": true,
    "bs-dependencies": ["bs-react-native","reason-react"],
    "sources": [{"dir": "re"}],
    "refmt": 3
    }

    View Slide

  57. New Project
    npm install -g bs-platform;
    create-react-app App !--scripts-version reason-scripts;

    View Slide

  58. Demo

    View Slide

  59. Resources
    • https://reasonml.github.io
    • https://bucklescript.github.io
    • https://reasonml.github.io/reason-react/en/

    View Slide

  60. Chicago
    ReasonML
    Meetup
    Google it. Come hang out & code.

    View Slide

  61. ChicagoJS.org
    Apply to talk at JSCamp by July 4th!

    View Slide

  62. Thanks
    Peter Piekarczyk
    @peterpme
    draftbit.com
    June 27, 2018

    View Slide