Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Use ReasonML in your React applications (RuhrJS...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
David Kopal
October 14, 2018
Programming
320
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Use ReasonML in your React applications (RuhrJS 2018)
David Kopal
October 14, 2018
More Decks by David Kopal
See All by David Kopal
Write better React (v3 ReasonReact)
codinglawyer
0
680
Use Reason in your React applications
codinglawyer
3
610
Unleash the power of the higher-order components
codinglawyer
2
290
Other Decks in Programming
See All in Programming
Webの地図
yosuke_furukawa
PRO
6
4.7k
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
250
Heart of Swift Concurrency
koher
0
960
Agents on Rails - Rails at Scale 2026
irinanazarova
0
170
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
500
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
320
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
260
JRuby: Past, Present, and Future
headius
0
180
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
150
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
170
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
460
AHC070解法紹介
eijirou
0
130
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Mind Mapping
helmedeiros
1
370
Making the Leap to Tech Lead
cromwellryan
135
10k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
500
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
Building an army of robots
kneath
307
46k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
380
Transcript
÷÷÷÷÷÷≥≥≥ Use ReasonML in your React applications David Kopal
@coding_lawyer @coding_lawyer codinglawyer.io meetup organizer contributor I’m David Kopal
@coding_lawyer
@coding_lawyer Who heard about ason?
@coding_lawyer
@coding_lawyer Who wants to write better React?
@coding_lawyer React isn’t a native JavaScript library
@coding_lawyer
@coding_lawyer Immutability
@coding_lawyer Immutability
@coding_lawyer Immutability
@coding_lawyer Immutability Functional programming
@coding_lawyer Immutability Functional programming
@coding_lawyer Immutability Functional programming
@coding_lawyer Immutability Type system Functional programming
@coding_lawyer Immutability Type system Functional programming
@coding_lawyer Immutability Type system Functional programming
@coding_lawyer Immutability Type system Functional programming
@coding_lawyer Immutability Type system Functional programming
@coding_lawyer Immutability Type system Functional programming
@coding_lawyer Immutability Type system Functional programming
@coding_lawyer
@coding_lawyer semantics familiar syntax
@coding_lawyer let fizzbuzz = (i) => switch (i mod 3,
i mod 5) { | (0, 0) => "FizzBuzz" | (0, _) => "Fizz" | (_, 0) => "Buzz" | _ => string_of_int(i) }; for (i in 1 to 100) { Js.log(fizzbuzz(i)) };
@coding_lawyer compiler
@coding_lawyer 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' } } for (var i = 1; i <= 100; ++i) { console.log(fizzbuzz(i)) } let fizzbuzz = (i) => switch (i mod 3, i mod 5) { | (0, 0) => "FizzBuzz" | (0, _) => "Fizz" | (_, 0) => "Buzz" | _ => string_of_int(i) }; for (i in 1 to 100) { Js.log(fizzbuzz(i)) };
@coding_lawyer JavaScript interop
@coding_lawyer
@coding_lawyer Reason is compatible with React
@coding_lawyer Reason is compatible with React React was developed for
Reason
@coding_lawyer adjusted JavaScript to React’s needs
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer semantics familiar syntax
@coding_lawyer safer React
@coding_lawyer “[Reason] is the best way to take React to
the next level” Jordan Walke, creator of Reason, React
@coding_lawyer Tic Tac Toe github.com/codinglawyer/reason-tic-tac-toe
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer components
@coding_lawyer stateless component
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer let component = ReasonReact.statelessComponent("App"); let make = _children =>
{ ...component, render: _self => <div> <div className=“title"> (ReasonReact.string("Tic Tac Toe")) </div> <Game /> </div>, };
@coding_lawyer let component = ReasonReact.statelessComponent("App"); let make = _children =>
{ ...component, render: _self => <div> <div className="title"> (ReasonReact.string("Tic Tac Toe")) </div> <Game /> </div>, };
@coding_lawyer let component = ReasonReact.statelessComponent("App"); let make = _children =>
{ ...component, render: _self => <div> <div className="title"> (ReasonReact.string("Tic Tac Toe")) </div> <Game /> </div>, };
@coding_lawyer let component = ReasonReact.statelessComponent("App"); let make = _children =>
{ ...component, render: _self => <div> <div className="title"> (ReasonReact.string("Tic Tac Toe")) </div> <Game /> </div>, };
@coding_lawyer let component = ReasonReact.statelessComponent("App"); let make = _children =>
{ ...component, render: _self => <div> <div className=“title"> (ReasonReact.string("Tic Tac Toe")) </div> <Game /> </div>, };
@coding_lawyer reducer component
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer let component = ReasonReact.reducerComponent("Game"); let make = _children =>
{ ...component, initialState: () => { board: […], gameState:… }, reducer: (action: action, state: state) => switch (action) { | Restart => … | ClickSquare((id: string)) => … }, render: ({state, send}) => <div className="game"> <Board state onRestart=(_evt => send(Restart)) onMark=(id => send(ClickSquare(id))) /> </div>, };
@coding_lawyer reducer: (action: action, state: state) => switch (action) {
| Restart => ReasonReact.Update(initialState) | ClickSquare((id: string)) => let updatedBoard = updateBoard( state.board, state.gameState, id); let updatedGs = checkGameState3x3( updatedBoard, state.board, state.gameState); ReasonReact.Update({ board: updatedBoard, gameState: updatedGs, }); },
@coding_lawyer reducer: (action: action, state: state) => switch (action) {
| Restart => ReasonReact.Update(initialState) | ClickSquare((id: string)) => let updatedBoard = updateBoard( state.board, state.gameState, id); let updatedGs = checkGameState3x3( updatedBoard, state.board, state.gameState); ReasonReact.Update({ board: updatedBoard, gameState: updatedGs, }); },
@coding_lawyer reducer: (action: action, state: state) => switch (action) {
| Restart => ReasonReact.Update(initialState) | ClickSquare((id: string)) => let updatedBoard = updateBoard( state.board, state.gameState, id); let updatedGs = checkGameState3x3( updatedBoard, state.board, state.gameState); ReasonReact.UpdateWithSideEffects( { board: updatedBoard, gameState: updatedGs, }, (_self => Js.log(“Clicked")), ); },
@coding_lawyer pure state update and side-effects separation
@coding_lawyer less boilerplate
@coding_lawyer Redux’s principles and component’s reusability
@coding_lawyer type system
@coding_lawyer clearer and safer code
@coding_lawyer superior to Flow and TypeScript
@coding_lawyer type inference
@coding_lawyer !/* type inference by the compiler !*/ let plus
= (a, b) !=> a + b
@coding_lawyer !/* type inference by the compiler !*/ let plus
= (a, b) !=> a + b !/* (int, int) !=> int !*/
@coding_lawyer type field = | Empty | Marked(player); type gameState
= | Playing(player) | Winner(player) | Draw; type player = | Cross | Circle;
@coding_lawyer type field = | Empty | Marked(player); type gameState
= | Playing(player) | Winner(player) | Draw; type player = | Cross | Circle;
@coding_lawyer type field = | Empty | Marked(player); type gameState
= | Playing(player) | Winner(player) | Draw; type player = | Cross | Circle;
@coding_lawyer type field = | Empty | Marked(player); type gameState
= | Playing(player) | Winner(player) | Draw; type player = | Cross | Circle;
@coding_lawyer type field = | Empty | Marked(player); type gameState
= | Playing(player) | Winner(player) | Draw; type player = | Cross | Circle;
@coding_lawyer
@coding_lawyer pattern matching
@coding_lawyer Game Board App BoardRow Square
@coding_lawyer reducer: (action: action, state: state) => switch (action) {
| Restart => ReasonReact.Update(initialState) | ClickSquare((id: string)) => let updatedBoard = updateBoard( state.board, state.gameState, id); let updatedGs = checkGameState3x3( updatedBoard, state.board, state.gameState); ReasonReact.Update({ board: updatedBoard, gameState: updatedGs, }); },
@coding_lawyer let updateBoard = (board: board, gameState: gameState, id) =>
board |> List.mapi((ind: int, row: row) => row |> List.mapi((index: int, value: field) => string_of_int(ind) ++ string_of_int(index) === id ? switch (gameState, value) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty } : value ) );
@coding_lawyer let updateBoard = (board: board, gameState: gameState, id) =>
board |> List.mapi((ind: int, row: row) => row |> List.mapi((index: int, value: field) => string_of_int(ind) ++ string_of_int(index) === id ? switch (gameState, value) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty } : value ) );
@coding_lawyer type field = | Empty | Marked(player); type gameState
= | Playing(player) | Winner(player) | Draw;
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty }
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty }
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty }
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty }
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty }
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty }
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) | (_, _) => Empty }
@coding_lawyer /* determines the value of the clicked square */
switch (gameState: gameState, value: field) { | (Playing(_), Marked(_)) => value | (Playing(player), Empty) => Marked(player) /* | (_, _) => Empty */ }
@coding_lawyer
@coding_lawyer switch ( getWinner(flattenBoard, head), gameEnded(flattenBoard), tail, ) { |
(Cross, _, _) => Winner(Cross) | (Circle, _, _) => Winner(Circle) | (_, true, []) => Draw | (_, false, []) => whosPlaying(gameState) | _ => check(tail) };
@coding_lawyer switch (match$1) { case 0 : return /* Winner
*/Block.__(1, [/* Cross */0]); case 1 : return /* Winner */Block.__(1, [/* Circle */1]); case 2 : if (match$2) { if (tail) { _rest = tail; continue ; } else { return /* Draw */0; } } else if (tail) { _rest = tail; continue ; } else { return whosPlaying(gameState); } }
@coding_lawyer Why should you use React in Reason?
@coding_lawyer Reason is compatible with React's principles
@coding_lawyer strong type system
@coding_lawyer pattern matching
@coding_lawyer functional programming features
@coding_lawyer stateless and stateful component separation
@coding_lawyer JavaScript-like syntax React friendly
@coding_lawyer Get your hands dirty! sketch.sh
@coding_lawyer codinglawyer.io @coding_lawyer
@coding_lawyer Thank You
@coding_lawyer @coding_lawyer codinglawyer.io github.com/codinglawyer/reason-tic-tac-toe