Slide 1

Slide 1 text

| @sdaigo Reason - > Melange - > fun Netadashi Meetup #12 2024.2.2

Slide 2

Slide 2 text

ઃᒜ େޛ Frontend dev @sdaigo

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems. https://reasonml.github.io/

Slide 5

Slide 5 text

An industrial-strength functional programming language with an emphasis on expressiveness and safety https://ocaml.org/

Slide 6

Slide 6 text

JS-like ʹॻ͚Δ OCaml ͷߏจ

Slide 7

Slide 7 text

let rec f i zzbuzz n = match (n mod 3, n mod 5) with | 0, 0 -> "FizzBuzz" | 0, _ -> "Fizz" | _, 0 -> "Buzz" | _, _ -> string_of_int n let _ = for i = 1 to 100 do f i zzbuzz i |. print_endline done let rec f i zzbuzz = n => switch (n mod 3, n mod 5) { | (0, 0) => "FizzBuzz" | (0, _) => "Fizz" | (_, 0) => "Buzz" | _ => string_of_int(n) }; let _ = for (i in 1 to 100) { f i zzbuzz(i) -> print_endline; };

Slide 8

Slide 8 text

JavaScript ʹίϯύΠϧͰ͖Δ

Slide 9

Slide 9 text

let rec f i zzbuzz = n => switch (n mod 3, n mod 5) { | (0, 0) => "FizzBuzz" | (0, _) => "Fizz" | (_, 0) => "Buzz" | _ => string_of_int(n) }; let _ = for (i in 1 to 100) { f i zzbuzz(i) -> print_endline; };

Slide 10

Slide 10 text

// Generated by Melange function f i zzbuzz(n) { var match = n % 3; var match$1 = n % 5; if (match != = 0) { if (match$1 != = 0) { return String(n); } else { return "Buzz"; } } else if (match$1 != = 0) { return "Fizz"; } else { return "FizzBuzz"; } } for(var i = 1; i < = 100; ++ i){ console.log(f i zzbuzz(i)); } export { f i zzbuzz , } /* Not a pure module * /

Slide 11

Slide 11 text

ݴޠϨϕϧͰ JSX Λαϙʔτ

Slide 12

Slide 12 text

module Greeting = { [@react.component] let make = () => { {React.string("Hello!")} ; }; }; ReactDOM.querySelector("#preview") -> ( fun | Some(root) => ReactDOM.render( , root) | None => Js.Console.error( "Failed to start React: couldn't f i nd the #preview element", ) );

Slide 13

Slide 13 text

/ / Generated by Melange import * as ReactDom from "react - dom"; import * as JsxRuntime from "react/jsx - runtime"; function _none_$Greeting(Props) { return JsxRuntime.jsx("button", { children: "Hello!" }); } var Greeting = { make: _none_$Greeting }; var param = document.querySelector("#preview"); if (param == null) { console.error("Failed to start React: couldn't f i nd the #preview element"); } else { ReactDom.render(JsxRuntime.jsx(_none_$Greeting, {}), param); } export { Greeting , } / * param Not a pure module * /

Slide 14

Slide 14 text

׬શͳܕਪ࿦Λ൐͏੩తܕ෇͚

Slide 15

Slide 15 text

// (array(option('a)), int) = > bool let isNotEmptyAt = (board, i) => board[i] - > Belt.Option.isSome; // (array('a), int, 'a) => array('a) let update = (board, pos, turn) => board -> Belt.Array.mapWithIndex((i, x) => i == pos ? turn : x); // (array('a), 'a) => bool let isWon = (board, turn) = > { won -> Belt.Array.map(row = > { let (c1, c2, c3) = row; [ | c1, c2, c3 |]-> Belt.Array.every(c = > board[c] == turn); }) -> Belt.Array.some(Fun.id); };

Slide 16

Slide 16 text

React to the Future ReasonConf US 2019 https://youtu.be/5fG_lyNuEAw

Slide 17

Slide 17 text

https://en.wikipedia.org/wiki/Reason_(programming_language)

Slide 18

Slide 18 text

https://en.wikipedia.org/wiki/Reason_(programming_language) https://en.wikipedia.org/wiki/React_(software)

Slide 19

Slide 19 text

Overview

Slide 20

Slide 20 text

API - Stdlibʢඪ४ϥΠϒϥϥϦʣ: OCaml ͱ΄΅ಉ͡΋ͷ - Belt : σʔλߏ଄ͱίϨΫγϣϯܕ - Js : ϒϥ΢βͱ Node JavaScript API ΁ͷόΠϯσΟϯά DOM / JSͷAPI + Ramda/LodashͷΑ͏ͳϥΠϒϥϦ͕ ಉࠝ͞Ε͍ͯΔͱࢥ͍ͬͯͩ͘͞

Slide 21

Slide 21 text

pipe pipe-first ( -> ) pipe-last ( |> ) let square = x => x * x; let sum = List.fold_left((+), 0); // succ(square(3)) 3 |> square |> succ; /* 10 */ [1, 2, 3] |> List.map(square) |> sum; /* [3, 4, 5] */ let square = x => x * x; let sum = List.fold_left((+), 0); // succ(square(3)) 3->square->succ; /* 10 */ [1, 2, 3] -> Belt.List.map(square) -> sum; /* [3, 4, 5] */

Slide 22

Slide 22 text

Functions are curried *default* // int -> int -> int let add = (x, y) => x + y; let plus1 = add(1); let plus2 = add(2); plus1(10); /* 11 */ plus2(10); /* 12 */ [1, 2, 3] ->Belt.List.map(plus2) ->Js.log; /* [3, 4, 5] */

Slide 23

Slide 23 text

if-else (expression) let condition = true; // if/else ͸「ࣜ」 // then, else Ͱಉ͡ܕΛฦ͢ඞཁ͕͋Δʢthen͚۟ͩ͸Ͱ͖ͳ͍ʣ let result = if (condition)ɹ{ “true"; } else { “false” }; result /* true */

Slide 24

Slide 24 text

Pattern matching factorial(3) /* 6 */ let rec factorial = n => switch (n) { | 1 = > 1 | _ = > n * factorial(n - 1); };

Slide 25

Slide 25 text

variants type color = | Red | Green | Blue | RGB(int, int, int); let components = c => switch (c) { | Red => (255, 0, 0) | Green => (0, 255, 0) | Blue => (0, 0, 255) | RGB(r, g, b) => (r, g, b) };

Slide 26

Slide 26 text

option let rec lookup = (x, lst) => switch (lst) { | [] => None | [(k, v), ... t] => if (x == k) { Some(v); } else { lookup(x, t); } };

Slide 27

Slide 27 text

Result let safe_divide = (x, y) => y == 0 ? Error("Division by zero") : Ok(x / y);

Slide 28

Slide 28 text

🚫

Slide 29

Slide 29 text

શମతʹݹ͍ʁ

Slide 30

Slide 30 text

Reason > JS ͸ BuckleScript Ͱ τϥϯεύΠϧ͞Ε͍ͯͨ

Slide 31

Slide 31 text

2020೥ɺBuckleScript ͕ ReScript ΁Ϧϒϥϯυ https://rescript-lang.org/blog/bucklescript-is-rebranding

Slide 32

Slide 32 text

Reason ͱͷޙํޓ׵ੑΛҡ࣋ͭͭ͠΋ɺΑΓJavaScript ͷ ΤίγεςϜͱͷ౷߹ΛਐΊɺಠࣗͷߏจΛ࣋ͭ ϓϥοτϑΥʔϜʹͳͬͨ 2020೥ɺBuckleScript ͕ ReScript ΁Ϧϒϥϯυ

Slide 33

Slide 33 text

Reasonࣗମ͸ OCaml ͷߏจͰɺͦͷ։ൃࣗମ͕ετοϓ͢ΔΘ͚Ͱ͸ͳ͘ JavaScript ΁ͷτϥϯεύΠϥ͕ແ͘ͳͬͯ͠·ͬͨܗ͕ͩ ࠞཚ͕ى͜ΓɺঃʑʹԼՐʹͳ͍ͬͯ͘… https://github.com/reasonml/reason/issues/2634#issuecomment-745218374 2020೥ɺBuckleScript ͕ ReScript ΁Ϧϒϥϯυ

Slide 34

Slide 34 text

🤔 🤔 🤔

Slide 35

Slide 35 text

// Generated by Melange import * as ReactDom from "react - dom"; import * as JsxRuntime from "react/jsx - runtime"; function _none_$Greeting(Props) { return JsxRuntime.jsx("button", { children: "Hello!" }); } . . . 👈

Slide 36

Slide 36 text

/ / Generated by Melange ™

Slide 37

Slide 37 text

Melange = New OCaml to JS ίϯύΠϥ Melange BuckleScript ΛϑΥʔΫͯ͠ 2022 ೥ʹ ొ৔͠ ͔͜͜Β OCaml ͷΤίγεςϜʹ໭Γ࢝ΊΔ

Slide 38

Slide 38 text

Ahrefs ͱ͍͏اۀ͕ओಋͰ։ൃΛਐΊ͍ͯͯ ͢ͰʹϑϧελοΫͰ OCaml Λ࠾༻͍ͯ͠Δ https://tech.ahrefs.com/ahrefs-is-now-built-with-melange-b14f5ec56df4

Slide 39

Slide 39 text

React 18Ҏ߱΁ͷ௥ै΍ɺRSC΁ͷରԠ͸͜Ε͔Β https://github.com/ml-in-barcelona/server-reason-react https://github.com/ml-in-barcelona/fullstack-reason-react-demo https://github.com/andreypopp/mlx Experimentalͳ࣮૷ Server Reason React Full stack ReasonReact mlx - OCaml syntax dialect which adds to JSX expression Node.js x 10 / Bun x 6

Slide 40

Slide 40 text

͜Ε͔Β࢝ΊΔͨΊͷϦιʔε https://melange.re/ https://chat.openai.com/g/g-CMdXZ3UYm-melange-mentor https://reasonml.github.io/ Melange Melange Mentor Reason https://ocaml.org/ OCaml https://reasonml.github.io/reason-react/ ReasonReact https://react-book.melange.re/intro/ Melange for React developers https://github.com/dmmulroy/create-melange-app create - melange - app https://dune.build/ Dune

Slide 41

Slide 41 text

https://melange-doc-ja.vercel.app/ ೔ຊޠυΩϡϝϯταΠτΛ࡞Γ·ͨ͠ʂ