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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
1.6k
FreeBSDでZabbixを動かす
kenkino
0
300
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
340
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
170
アクセシビリティから考える情報設計
high_g_engineer
0
380
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
190
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
250
海上で動くGoサーバー: goroutineとchannelでさばく航行データストリーム
atsuki_seo
0
720
Are APIs Still Relevant in the AI Era?
soyuka
0
250
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
290
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
180
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
550
Featured
See All Featured
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
350
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
990
Marketing to machines
jonoalderson
1
5.8k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
530
Joys of Absence: A Defence of Solitary Play
codingconduct
1
520
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
3
4.3k
Everyday Curiosity
cassininazir
0
320
GraphQLとの向き合い方2022年版
quramy
50
15k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Leo the Paperboy
mayatellez
10
2.3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.8k
The Limits of Empathy - UXLibs8
cassininazir
1
680
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