ReasonML @ OCaml Users in Paris

ReasonML @ OCaml Users in Paris

37500337ba5d2aebc962959ed83928e5?s=128

Matthias Le Brun

September 26, 2017
Tweet

Transcript

  1. REASON

  2. Matthias Le Brun twitter.com/bloodyowl github.com/bloodyowl Putain de code !

  3. OCaml

  4. let rec qsort = function | [] !-> [] |

    pivot #:: rest !-> let is_less x = x < pivot in let left, right = List.partition is_less rest in qsort left @ [pivot] @ qsort right
  5. Syntax isn't really friendly to newcomers

  6. FP communities aren’t really welcoming to newcomers

  7. None
  8. Here comes Reason

  9. Storytime •Initially, React was written in SML by Jordan Walke

    •The idea for Reason actually predates React •Front-end community wasn’t ready yet
  10. 1. Syntax 2. Tooling 3. Ecosystem 4. Community

  11. 1. Syntax 2. Tooling 3. Ecosystem 4. Community

  12. Functions let x a b = e let x =

    fun a b !-> e OCaml Reason let x a b %=> e; let x = fun a b %=> e;
  13. Equality a = b b '== c a #<> b

    a *!= b OCaml Reason a '== b b ##=== c a *!= b a --!== b
  14. Expressions let c = let a = "a" in let

    b = "b" in a ^ b OCaml Reason let c = { let a = "a"; let b = "b"; a ^ b };
  15. Tuples type tup = int * int let tuple =

    a, b OCaml Reason type tup = (int, int) let tuple = (a, b)
  16. Record types type rec = { foo: string; bar: string

    }; OCaml Reason type rec = { foo: string, bar: string };
  17. Records { foo = "bar"; bar = "baz" } OCaml

    Reason { foo: "bar", bar: "baz", }
  18. Lists [1; 2; 3] OCaml Reason [1, 2, 3]

  19. Type params string option list OCaml Reason list (option string)

  20. Variants type foo = | A of string | B

    of string OCaml Reason type foo = | A string | B string
  21. Pattern matching match a with | A x %=> "A"

    ^ x | B x %=> "B" ^ x OCaml Reason switch a { | A x %=> "A" ^ x | B x %=> "B" ^ x }
  22. Equality (* comment *) OCaml Reason //* comment -*/

  23. Refmt: one language, one formatting

  24. ReasonFatigue prevented ☕

  25. Syntax simpler to JS folks

  26. 1. Syntax 2. Tooling 3. Ecosystem 4. Community

  27. BuckleScript

  28. BuckleScript •Like js_of_ocaml but takes on after an earlier step

    of compilation •Makes some optimisations considering the JS target •Great interoperability
  29. Produces code that’s faster than vanilla™

  30. Smaller footprint var user = //* record -*/[ //* username

    -*/"Bob", //* id : Some -*/["abc"], //* age -*/32 ];
  31. [ "Bob", ["abc"], 32 ]; Smaller footprint

  32. Don’t want to rewrite your project from scratch?

  33. external myExistingModule : string = [@@bs.module "-../myExistingModule"]; Use JS

  34. type user = { name: string, age: int }; let

    fromJs jsObject %=> { name: jsObject###name, age: jsObject###age }; Convert from JS
  35. let toJs object %=> { "name": object.name, "age": object.age };

    Convert to JS
  36. { "message_type": "image" | "string", "value": string } Complex conversions

  37. type message = | Image string | String string; let

    fromJs js %=> { switch js###message_type { | "image" %=> Image js###value | "string" | _ %=> String js###value } } Complex conversions
  38. Lots of bindings existing/on the way

  39. let getPageKeywords () %=> switch ( DomRe.Document.querySelector "meta[name=\"keywords\"]" DomRe.document )

    { | Some meta %=> switch (DomRe.Element.getAttribute "content" meta) { | Some content %=> Js.String.split "," content *|> Array.to_list *|> List.map String.trim | None %=> [] } | None %=> [] };
  40. None
  41. BetterErrors

  42. Simpler workflow •Effort is for now a lot on the

    JS back-end •Coming for native compilation
  43. 1. Syntax 2. Tooling 3. Ecosystem 4. Community

  44. ReasonReact

  45. ReactJS import React from "react"; import { string } from

    "prop-types"; const App = props %=> ( <div> {props.message} !</div> ) App.propTypes = { message: string.isRequired };
  46. ReasonReact let component = ReasonReact.statelessComponent "App"; let make #::message _children

    %=> { …component, render: fun _ %=> <div> (ReasonReact.stringToElement message) !</div> };
  47. ReasonReact type state = int; type actions = | Increment

    | Decrement;
  48. ReasonReact let component = ReasonReact .reducerComponent "App"; let make _

    %=> { …component, reducer: fun action state %=> switch action { | Increment %=> ReasonReact.Update (state + 1) | Decrement %=> ReasonReact.Update (state - 1) }, //* … -*/ }
  49. ReasonReact render: fun {state, reduce} %=> <div> (ReasonReact.stringToElement (string_of_int state))

    <Button title="-" onClick=(reduce (fun _ %=> Increment)) 6/> !</div>
  50. <div> (switch resource { | Loading %=> <ActivityIndicator 6/> |

    Idle value %=> <Component value 6/> | Error %=> ErrorMessage.serverError }) !</div> ReasonReact
  51. module MyType = { let name = "Type"; type t

    = string; }; module MyTypeCollectionView = Primitives.FixedCollectionView.Make MyType; <MyTypeCollectionView items 6/> ReasonReact
  52. let jsComponent = ReasonReact.wrapReasonForJs #::component (fun jsProps %=> make message#::jsProps###message

    [#||] ); ReasonReact
  53. let make #::message children %=> ReasonReact.wrapJsForReason #::reactClass props#::{"message": message} children;

    ReasonReact
  54. ReasonReact: good entry point for the front-end community

  55. 1. Syntax 2. Tooling 3. Ecosystem 4. Community

  56. Community

  57. Lots of meetups popping up

  58. 1. Syntax 2. Tooling 3. Ecosystem 4. Community Sum up

  59. • A new, simpler syntax for OCaml • Lots of

    efforts in improving tooling (BetterErrors, BuckleScript is a friend project) • New features like JSX • A new community (super active at the moment) • A great core team who knows what to prioritise first to make it good for everyone
  60. Thank you! Questions?