Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Use ReasonML in your React applications (RuhrJS...
Search
David Kopal
October 14, 2018
Programming
310
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
670
Use Reason in your React applications
codinglawyer
3
610
Unleash the power of the higher-order components
codinglawyer
2
280
Other Decks in Programming
See All in Programming
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
5
550
高専、大学編入、そして未踏へ〜プロダクト開発とキャリアの歩み - Technical College, University Transfer, and On to “Mitou” / My Journey in Product Development and Career
pkmiya
0
100
Deep dive into the select statement (GopherCon UK)
jespino
0
150
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
560
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
310
AIに既存システムを理解させる技術 ~レガシーを見捨てないハーネスエンジニアリング入門~
ochtum
0
170
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
7
2.2k
typoなんかねぇよ
raspython3
0
610
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
3
2.2k
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
230
バグを直したら useEffect が消えた
colorful12
3
760
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
160
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
260
Into the Great Unknown - MozCon
thekraken
41
2.7k
WCS-LA-2024
lcolladotor
0
810
My Coaching Mixtape
mlcsv
0
300
The Curious Case for Waylosing
cassininazir
1
480
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
510
Code Reviewing Like a Champion
maltzj
528
40k
Docker and Python
trallard
47
4.2k
Facilitating Awesome Meetings
lara
57
7.1k
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