Matheus Albuquerque
October 04, 2022
41

# ๐ณ๐ฑ Frontmania 2022 - Insideย Fiber

โน๏ธ Inside Fiber: the in-depth overview you wanted a TLDR for

We'll have an in-depth overview of the important concepts behind reconciliation and React Fiber. Then, we'll explore how React uses this algorithm and go through a few magic words we hear a lot, like coroutines, continuations, generators, and algebraic effectsโand see how they all relate to React.

October 04, 2022

## Transcript

1. ### Hello, Frontmania! โ ๐ณ๐ฑ INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR โข THE 5TH OF OCTOBER, 2022.

TLDR FOR
3. ### IโM MATHEUS ๐ โ @YTHECOMBINATOR ON THE WEB โ SR.

SOFTWARE ENGINEER @MEDALLIA โ MENTOR @TECHLABS

FOR
5. ### #1 REACT SOURCE CODE IS CONSTANTLY CHANGING, AND SOME THOUGHTS

ARE SPECULATIONS INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
6. ### #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR ๐คฏ = DEEP DIVE ๐คฟ, FURTHER DISCUSSIONS AFTER THE SESSION
7. ### A bit of context INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

FOR
13. ### function add(x,y) { const result = x + y; return

result; } add(2, 2) STACK FRAMES
14. ### let frame: Frame = { return: frame, fn: add, parameters:

[2, 2], localVariables: { result: 4, }, } STACK FRAMES
15. ### let frame: Frame = { return: frame, fn: add, parameters:

[2, 2], localVariables: { result: 4, }, } let fiber: Fiber = { return: fiber, component: Avatar, props: { id: 4 }, state: { isLoaded: true, }, } STACK FRAMES
16. ### โ FIBER ARCHITECTURE โข REACT-SPECIFIC IMPLEMENTATION OF A CALL-STACK-LIKE MODEL

WHERE REACT HAS FULL CONTROL OF SCHEDULING WHAT SHOULD BE DONE โ FIBER โข A STACK FRAME FOR A REACT COMPONENT FIBERS
17. ### Fibers as Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW

YOU WANTED A TLDR FOR
18. ### ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
19. ### ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
20. ### ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
21. ### ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE.
22. ### ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. A UNIT OF WORK.
23. ### ONCE A TEMPLATE GOES THROUGH THE JSX COMPILER, YOU END

UP WITH A BUNCH OF REACT ELEMENTS. DURING RECONCILIATION, DATA FROM EVERY REACT ELEMENT RETURNED FROM THE RENDER METHOD IS MERGED INTO THE TREE OF FIBER NODES. DEPENDING ON THE TYPE OF A REACT ELEMENT THE FRAMEWORK NEEDS TO PERFORM DIFFERENT ACTIVITIES. EACH ELEMENT IS CONVERTED INTO A FIBER NODE THAT DESCRIBES THE WORK THAT NEEDS TO BE DONE. A UNIT OF WORK. AND THAT MAKES IT A CONVENIENT WAY TO TRACK, SCHEDULE, PAUSE AND ABORT THE WORK.
24. ### Visualizing Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

26. None
27. None
28. ### let fiberNode = fiberRoot.current; let fibersMap = new Map(); while

(fiberNode) { if (fiberNode.stateNode ! = = null) { fibersMap.set(fiberNode.stateNode, fiberNode); } if (fiberNode.child === null) { while (fiberNode ! = = null & & fiberNode.sibling === null) { fiberNode = fiberNode.return; } fiberNode = fiberNode?.sibling; continue; } fiberNode = fiberNode.child; }
29. ### let fiberNode = fiberRoot.current; let fibersMap = new Map(); while

(fiberNode) { if (fiberNode.stateNode ! = = null) { fibersMap.set(fiberNode.stateNode, fiberNode); } if (fiberNode.child === null) { while (fiberNode ! = = null & & fiberNode.sibling === null) { fiberNode = fiberNode.return; } fiberNode = fiberNode?.sibling; continue; } fiberNode = fiberNode.child; } ๐คฏ
30. None

33. ### Manipulating Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

36. ### (let [x 1] (inc x)) ; = > 2 HOMOICONICITY

PERFORMS A TEMPORARY BINDING (BINDS X TO THE VALUE 1)
37. ### INCREMENTS X TO GIVE THE RETURN VALUE OF 2 (let

[x 1] (inc x)) ; = > 2 HOMOICONICITY
38. ### IT CAN BE THOUGHT OF AS A LIST WITH THREE

ELEMENTS โ A SYMBOL NAMED LET โ A VECTOR WITH TWO ELEMENTS โ A LIST WITH TWO ELEMENTS HOMOICONICITY
39. ### IT CAN BE THOUGHT OF AS A LIST WITH THREE

ELEMENTS โ A SYMBOL NAMED LET โ A VECTOR WITH TWO ELEMENTS โ A LIST WITH TWO ELEMENTS HOMOICONICITY A SYMBOL (X) AND AN INTEGER A SYMBOL (INC) AND A SYMBOL (X)
40. ### #QUOTE ๐ค โโฆHomoiconicity is a property of some programming languages

in which the code used to express a program is written using the data structures of that language.โ โโWikipedia
41. ### โ REACT ELEMENTS ARE JUST DATA โ JUST LIKE IN

LISP, REACT COMPONENTS CAN MANIPULATE THEIR CHILDREN AND RETURN COMPLETELY DIFFERENT THINGS HOMOICONICITY

43. ### #QUOTE ๐ค โ[โฆ] Pattern matching consists of specifying patterns to

which some data should conform and then checking to see if it does and deconstructing the data according to those patterns.โ โโLearn You a Haskell
44. ### factorial : : (Integral a) = > a - >

a factorial 0 = 1 factorial n = n * factorial (n - 1) PATTERN MATCHING
45. ### fib : : (Integral a) = > a - >

a fib 0 = 1 fib 1 = 1 fib n | n > = 2 = fib (n-1) + fib (n-2) PATTERN MATCHING factorial =

47. ### / / . . . export function isWhen<Shape extends {}>(

child: ElementWithMetadataUnion<Shape> ): child is ElementWithMetadata<WhenProps<Shape > > { return child.element.type === When; } / / . . . export function nodesToElementWithMetadata<Shape extends {}>( children: ReactNode ) { return Children.toArray(children).map((element, idx) = > ({ element: element, position: idx, })) as Array<ElementWithMetadata<Shape > > ; } / / . . .
48. ### / / . . . export function isWhen<Shape extends {}>(

child: ElementWithMetadataUnion<Shape> ): child is ElementWithMetadata<WhenProps<Shape > > { return child.element.type === When; } / / . . . export function nodesToElementWithMetadata<Shape extends {}>( children: ReactNode ) { return Children.toArray(children).map((element, idx) = > ({ element: element, position: idx, })) as Array<ElementWithMetadata<Shape > > ; } / / . . .
49. ### const supportsSensor = () = > Boolean(window.AmbientLightSensor); const AmbientLight =

React.lazy(() = > import("./AmbientLight")); const Fallback = React.lazy(() = > import("./Fallback")); export default function MyComponent() { const { Match, When, Otherwise } = usePatternMatch(); return ( <Suspense fallback="Loading"> <Match> <When predicate={supportsSensor}> <AmbientLight /> </When> <Otherwise> <Fallback /> </Otherwise> </Match> </Suspense> ); } PATTERN MATCHING
50. ### const supportsSensor = () = > Boolean(window.AmbientLightSensor); const AmbientLight =

React.lazy(() = > import("./AmbientLight")); const Fallback = React.lazy(() = > import("./Fallback")); export default function MyComponent() { const { Match, When, Otherwise } = usePatternMatch(); return ( <Suspense fallback="Loading"> <Match> <When predicate={supportsSensor}> <AmbientLight /> </When> <Otherwise> <Fallback /> </Otherwise> </Match> </Suspense> ); } PATTERN MATCHING + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE COMPONENT BUNDLE THAT MATCHES
51. ### const supportsSensor + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY

THE COMPONENT BUNDLE THAT MATCHES MANIPULATING BASED ON ELEMENTS DATA.

53. ### USING FIBERS, REACT CAN: โ PAUSE, RESUME, AND RESTART RENDERING

WORK ON COMPONENTS AS NEW UPDATES COME IN โ REUSE PREVIOUSLY COMPLETED WORK โ SPLIT WORK INTO CHUNKS AND PRIORITIZE TASKS BASED ON IMPORTANCE FIBERS IN REACT (RECAP)

A TLDR FOR
55. ### โ A FIBER IS A GENERIC MODEL OF EXECUTION WHERE

EACH UNIT WORKS TOGETHER COOPERATIVELY โ FIBERS ARE A COMMON RESOURCE IN SOME OPERATING SYSTEMS (E.G. WINDOWS) AND IN SOME PROGRAMMING LANGUAGES (E.G. OCAML) FIBERS OUT THERE

FOR
58. None
59. ### #1 A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES. INSIDE

FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
60. ### #1 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR โ JAVASCRIPT GENERATORS CAN CONSUME VALUES โ BY THIS DEFINITION, THEY ARE COROUTINES A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES.
61. ### #2 A GENERATOR THAT CAN RESOLVE ASYNCHRONOUS VALUES, LIKE ASYNC/AWAIT.

INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
62. ### #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR โ THIS IS THE MOST COMMON MEANING OF โCOROUTINEโ IN THE JAVASCRIPT WORLD โ WE HAD CO AND BLUEBIRD, WHICH HAD ASYNC/AWAIT IMPLEMENTATIONS BASED ON GENERATORS VALUES, LIKE ASYNC/AWAIT.
63. ### #3 A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION

INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
64. ### #3 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR โ "DEEP AWAIT" โ e.g. WITH SUSPENSE, WE CAN PAUSE RECONCILIATION AT ANY DEPTH A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION
65. ### Fibers CONTROL IS PASSED TO A SCHEDULER WHICH DETERMINES WHAT

TO RUN NEXT โ = CONTROLLED AT THE LEVEL OF THE OPERATING SYSTEM OR FRAMEWORK โ E.G. NODE.JS EVENT LOOP
66. ### Coroutines CONTROL IS PASSED TO THE CALLER AND HANDLED BY

APPLICATION CODE Fibers CONTROL IS PASSED TO A SCHEDULER WHICH DETERMINES WHAT TO RUN NEXT

A TLDR FOR
68. ### COROUTINES APPEARED WHEN WORK ON FIBER WAS FIRST GOING AS

A SPECIFIC COMPONENT TYPE. THE IDEA BEHIND COROUTINESโโโAS OPPOSED TO FIBERSโโโWAS TO GIVE COMPONENTS EXPLICIT CONTROL OVER YIELDING AND RESUMPTION.

70. ### COROUTINES & REACT โ COROUTINES PER SI IN REACT NO

LONGER EXIST. โ IT WILL BE FASCINATING TO SEE WHAT FORM COROUTINES TAKE WHEN THEY RETURN TO REACT FIBER.
71. ### Coroutines & Concurrent React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

74. ### function resourcefulOperation(value: number) { let newValue = String(value); for (let

i = 0; i < 1000000; i++) { newValue = `\${value} + \${i} = \${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }

78. None
79. ### function resourcefulOperation(value: number) { let newValue = String(value); for (let

i = 0; i < 1000000; i++) { newValue = `\${value} + \${i} = \${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
80. ### function* resourcefulOperation(value: number) { let newValue = String(value); while (true)

{ yield; for (let i = 0; i < 1000000; i++) { newValue = `\${value} + \${i} = \${value + i}`; } return newValue; } } const initialValue = 0; const scheduler = new Scheduler(resourcefulOperation, initialValue); function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = scheduler.performUnitOfWork(value); return <p>{result}</p>; }
81. ### function* resourcefulOperation(value: number) { let newValue = String(value); while (true)

{ yield; for (let i = 0; i < 1000000; i++) { newValue = `\${value} + \${i} = \${value + i}`; } return newValue; } } const initialValue = 0; const scheduler = new Scheduler(resourcefulOperation, initialValue); function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = scheduler.performUnitOfWork(value); return <p>{result}</p>; } PROMOTED TO A GENERATOR YIELDING EXECUTION DOING CONCURRENT TASKS

83. ### enum SchedulerState { IDLE = "IDLE", PENDING = "PENDING", DONE

= "DONE", } class Scheduler<T> { state: SchedulerState; result: T; worker: (data: T) = > Generator; iterator: Generator; constructor(worker: (data: T) = > Generator, initialResult: T) { this.state = SchedulerState.IDLE; this.worker = worker; this.result = initialResult; } performUnitOfWork(data: T) { switch (this.state) { case "IDLE": this.state = SchedulerState.PENDING; this.iterator = this.worker(data); throw Promise.resolve(); case "PENDING": const { value, done } = this.iterator.next(); if (done) { this.result = value; this.state = SchedulerState.DONE; return value; } throw Promise.resolve(); case "DONE": this.state = SchedulerState.IDLE; return this.result; } } }
84. ### performUnitOfWork(data: T) { switch (this.state) { case "IDLE": this.state =

SchedulerState.PENDING; this.iterator = this.worker(data); throw Promise.resolve(); case "PENDING": const { value, done } = this.iterator.next(); if (done) { this.result = value; this.state = SchedulerState.DONE; return value; } throw Promise.resolve(); case "DONE": this.state = SchedulerState.IDLE; return this.result; } }

86. ### function resourcefulOperation(value: number) { let newValue = String(value); for (let

i = 0; i < 1000000; i++) { newValue = `\${value} + \${i} = \${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const { value } = props; const result = resourcefulOperation(value); return <p>{result}</p>; }
87. ### function resourcefulOperation(value: number) { let newValue = String(value); for (let

i = 0; i < 1000000; i++) { newValue = `\${value} + \${i} = \${value + i}`; } return newValue; } function ResourcefulComponent(props: { value: number }) { const [_, startTransition] = useTransition(); const [result, setResult] = useState(""); useEffect(() = > { startTransition(() = > { const newResult = resourcefulOperation(props.value); setResult(newResult); }); }, [props.value]); return <p>{result}</p>; }

89. ### โ A COOPERATIVE MULTITASKING MODEL โ A SINGLE INTERRUPTIBLE RENDERING

THREAD โ RENDERING CAN BE INTERLEAVED WITH OTHER MAIN THREAD TASKS AND OTHER REACT RENDERS โ AN UPDATE CAN HAPPEN IN THE BACKGROUND WITHOUT BLOCKING THE RESPONSE TO NEW INPUT COROUTINES & SCHEDULING

91. ### โ IT YIELDS EXECUTION IS BACK TO THE MAIN THREAD

EVERY 5MS โ IT'S SMALLER THAN A SINGLE FRAME EVEN ON 120FPS, SO IT WON'T BLOCK ANIMATIONS โ IN PRACTICE, RENDERING IS INTERRUPTIBLE COROUTINES & SCHEDULING

93. ### COROUTINES & SCHEDULING ๐ NON-PRACTICALโฆ โ RENDERING MANY DATA-POINTS โ

RENDERING ON A <canvas> โ PROCESSING DATA

95. ### COROUTINES & SCHEDULING const DailyVisitors = () = > {

const [data, setData] = useState(initialData); useEffect(() = > { setData(initialData); }, []); const onChange = (newData) = > { setData(newData); }; return ( <Dashboard data={data} initialData={initialData} onChange={onChange} /> ); }; export default DailyVisitors;
96. ### COROUTINES & SCHEDULING const DailyVisitors = () = > {

const [data, setData] = useState(initialData); const [, startTransition] = useTransition(); useEffect(() = > { setData(initialData); }, []); const onChange = (newData) = > { startTransition(() = > { setData(newData); }); }; return ( <Dashboard data={data} initialData={initialData} onChange={onChange} /> ); }; export default DailyVisitors;

98. None

A TLDR FOR
101. ### โ ASYNCHRONY IN JAVASCRIPT IS CONTAGIOUS โ IF ANY FUNCTION

IS ASYNC, THEN EVERYTHING THAT CALLS IT MUST ALSO BE ASYNCโฆ โ โฆAND SO ON UNTIL THE ENTIRE PROGRAM IS ASYNCHRONOUS ๐คท ASYNCHRONY & JS
102. ### โ ASYNCHRONY IN JAVASCRIPT ISNโT FREE โ EVERY ASYNCHRONOUS FUNCTION

CALL HAS TO: โ ALLOCATE CALLBACKS & STORE THEM SOMEWHERE โ TAKE A TRIP BACK TO THE EVENT LOOP BEFORE INVOKING THOSE CALLBACKS ASYNCHRONY & JS

104. None
105. ### โ ITS API HAS TWO MAIN FUNCTIONS FOR COMPILING SASS

FILES: ONE SYNC AND ONE ASYNC โ THE ASYNC ONE BECAME WIDELY USED IN PRACTICE BECAUSE IT ENABLED ASYNC PLUGINS (E.G. WEBPACKโS SASS-LOADER) ASYNCHRONY & SASS
106. ### โ FOR NODE SASS, THE PERFORMANCE DIFFERENCE WAS NEGLIGIBLE, BECAUSE

IT WAS BUILT ON C++ โ HOWEVER, DART SASS RUNS AS PURE JAVASCRIPT, WHICH MAKES IT SUBJECT TO JAVASCRIPTโS ASYNC RULES ASYNCHRONY & SASS
107. ### โ THE ASYNC VERSION IN DART SASS WAS 2-3X SLOWER

THAN THE SYNC ONE โ THEY STARTED USING NODE-FIBERS TO IMPLEMENT THE ASYNC API USING THE FAST, SYNC, CODE ASYNCHRONY & SASS

109. None

TLDR FOR
111. ### ๐คฏ APPROACH TO REASONING ABOUT COMPUTATIONAL EFFECTS IN PURE CONTEXTS

โ EFFECT โข A SET OF OPERATIONS โ EFFECT HANDLER โข RESPONSIBLE FOR HANDLING THE SEMANTICS OF HOW TO IMPLEMENT EFFECTS EFFECT HANDLERS
112. ### (* state.eff *) type user = string * int effect

Get: user effect Set: user - > unit ๐คฏ EFFECT HANDLERS IN EFF
113. ### (* state.eff *) type user = string * int effect

Get: user effect Set: user - > unit A USER WITH A NAME AND AGE EFFECT HANDLERS IN EFF
114. ### (* state.eff *) type user = string * int effect

Get: user effect Set: user - > unit WE DEFINE EFFECTS WITH THE effect KEYWORD AND A TYPE SIGNATURE. EFFECT HANDLERS IN EFF
115. ### let state = handler | y - > fun currentState

- > (y, currentState) | effect Get k - > (fun currentState - > (continue k currentState) currentState) | effect (Set newState) k - > (fun _ - > (continue k ()) newState) ;; ๐คฏ EFFECT HANDLERS IN EFF
116. ### let state = handler | y - > fun currentState

- > (y, currentState) | effect Get k - > (fun currentState - > (continue k currentState) currentState) | effect (Set newState) k - > (fun _ - > (continue k ()) newState) ;; WE HAVE A handler WITH THREE BRANCHES, AND ALL OF THEM RETURN A FUNCTION. EFFECT HANDLERS IN EFF
117. ### let state = handler | y - > fun currentState

- > (y, currentState) | effect Get k - > (fun currentState - > (continue k currentState) currentState) | effect (Set newState) k - > (fun _ - > (continue k ()) newState) ;; NO EFFECT (WHEN WE REACH THE END OF THE BLOCK). y IS THE RETURN VALUE. EFFECT HANDLERS IN EFF
118. ### let state = handler | y - > fun currentState

- > (y, currentState) | effect Get k - > (fun currentState - > (continue k currentState) currentState) | effect (Set newState) k - > (fun _ - > (continue k ()) newState) ;; MATCHING OUR EFFECTS. EFFECT HANDLERS IN EFF
119. ### let state = handler | y - > fun currentState

- > (y, currentState) | effect Get k - > (fun currentState - > (continue k currentState) currentState) | effect (Set newState) k - > (fun _ - > (continue k ()) newState) ;; k IS A CONTINUATION. IT REPRESENTS THE REST OF THE COMPUTATION AFTER WHERE WE PERFORM AN EFFECT. EFFECT HANDLERS IN EFF

121. ### function getName(user) { let name = user.name; if (name ===

null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } }
122. ### function getName(user) { let name = user.name; if (name ===

null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } }
123. ### function getName(user) { let name = user.name; if (name ===

null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } } THROW โ PERFORM CATCH โ HANDLE LETS US JUMP BACK TO WHERE WE PERFORMED THE EFFECT
124. ### โ IT DOESN'T REALLY MATTER HOW WE HOLD STATE. IF

WE WERE TO CHANGE IN THE FUTURE, WEโD NEED TO START HANDLING PROMISES, WHICH WOULD REQUIRE CHANGES ACROSS EVERYTHING. โ WITH ALGEBRAIC EFFECTS, WE CAN SIMPLY STOP THE CURRENT PROCESS ALTOGETHER UNTIL OUR EFFECTS ARE FINISHED. EFFECT HANDLERS
125. ### Effect handlers in React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR
126. ### #1 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR LAYOUT ALGORITHM
127. ### THE REACT TEAM APPARENTLY SPENT SOME TIME EXPERIMENTING WITH EFFECT-

HANDLER CONTROL STRUCTURES FOR MANAGING LAYOUT

129. ### #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR CONTEXT API DRAFTS

132. ### #3 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR SIDE EFFECTS WITHIN A COMPONENT

134. ### function ThemeBorderColorRequest() { } function FancyBox(children) { const color =

raise new ThemeBorderColorRequest(); return { borderWidth: '1px', borderColor: color, children: children }; } function BlueTheme(children) { return try { children(); } catch effect ThemeBorderColorRequest - > [, continuation] { continuation('blue'); } } function App(data) { return BlueTheme( FancyUserList.bind(null, data.users) ); }
135. ### function ThemeBorderColorRequest() { } function FancyBox(children) { const color =

raise new ThemeBorderColorRequest(); return { borderWidth: '1px', borderColor: color, children: children }; } function BlueTheme(children) { return try { children(); } catch effect ThemeBorderColorRequest - > [, continuation] { continuation('blue'); } } function App(data) { return BlueTheme( FancyUserList.bind(null, data.users) ); } THROW โ RAISE CATCH โ CATCH EFFECT
136. ### #4 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR HOOKS API

139. ### HOOKS API โ ALGEBRAIC EFFECTS = A SET OF OPERATIONS

AND A SET OF EFFECT HANDLERS โ THE OPERATIONS HERE ARE OUR HOOKS (E.G. useState, useEffect, AND SO ON) โ WE HAVE TO SET UP HANDLERS IN EFF; IN REACT THEY'RE SET UP AS PART OF THE RENDER CYCLE
140. ### HOOKS API โ REACT IS RESPONSIBLE FOR MUCH OF THE

IMPLEMENTATION OF WHEN/HOW OUR EFFECTS RUN โ IT ALLOWS US TO STASH ENORMOUS AMOUNTS OF COMPLEXITY WITHIN REACT โ BY SPLITTING EFFECTS AND RENDERING, WE ALLOW IT TO RELIEVE US OF SOME COMPLEXITY
141. ### #5 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR SUSPENSE INTERNALS

143. None
144. None

146. ### A COMPONENT IS ABLE TO SUSPEND THE FIBER IT IS

RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK.
147. ### A COMPONENT IS ABLE TO SUSPEND THE FIBER IT IS

RUNNING IN BY THROWING A PROMISE, WHICH IS CAUGHT AND HANDLED BY THE FRAMEWORK. THROW โ HANDLE โ RESUME PATTERN.
148. ### Effect handlers out there INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU

WANTED A TLDR FOR

FOR
153. ### #QUOTE ๐ค โAt my heart, I am something like the

goto instruction; my creation sets the label, and my methods do the jump. However, this is a really powerful kind of goto instruction. [โฆ]โ โโGNU Smalltalk Continuation documentation
154. ### โ ITโS AN ABSTRACTION THAT REPRESENTS THE REMAINING STEPS IN

A COMPUTATION, AFTER WHERE WE PERFORM AN EFFECT. โ IT'S A CONTROL FLOW PRIMITIVE. โ DIFFERENT FROM goto. ALL THE VARIABLES, POINTERS, ETC. ARE VALID. CONTINUATIONS

158. ### โ IT HANDLES A QUEUE OF TASKS IN A WHILE

LOOP โ IF THERE ARE STILL TASKS ON THE QUEUE, IT RETURNS performWork AND SCHEDULE IT FOR RESUMPTION AT SOME LATER TIME โ IN THIS CONTEXT, IT REPRESENTS THE CONTINUATION OF A QUEUE OF TASKS CONTINUATIONS IN REACT

160. ### async function doWork() { while (true) { let hasMoreWork =

doSomeWork(); if (!hasMoreWork) { return; } if (!navigator.scheduling.isInputPending()) { continue; } await scheduler.yield(); } } ๐คฏ CONTINUATIONS ON THE WEB

163. ### INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Closing Notes
164. ### #1 REACT FIBER WAS A REWRITE OF REACT FOCUSED ON

GIVING MORE LOW-LEVEL CONTROL OVER PROGRAM EXECUTION INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
165. ### #1 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR โ FIBERS AS A LOW-LEVEL COOPERATIVE WAY TO MODEL EXECUTION โ ALGEBRAIC EFFECTS AS A WAY TO HANDLE EFFECTS WHERE THESE AND THEIR BEHAVIOR ARE INDEPENDENT EXECUTION
166. ### #2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR REACT TRIES TO ADDRESS THE LACK OF SOME JAVASCRIPT FEATURES/ LANGUAGE-LEVEL RESOURCES BY IMPLEMENTING SOME ALTERNATIVE SOLUTIONS TO ACHIEVE SIMILAR BEHAVIORS E.G. EFFECT HANDLERS & CONTINUATIONS
167. ### #3 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR UNDERSTANDING SOME OF THESE CONCEPTS GIVES US A BETTER MENTAL MODEL FOR WHAT SOME REACT FEATURES ARE DOING BEHIND THE SCENES E.G. HOOKS AND EFFECT HANDLERS
168. ### #4 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR UNDERSTANDING THESE INTERNALS AND THEIR RATIONALES HELPS US IMPLEMENT OUR OWN ABSTRACTIONS E.G. THE COROUTINES-BASED SCHEDULER & THE PATTERN MATCHING COMPONENTS
169. None
170. ### #5 THE FACT WE'RE DISCUSSING ALL OF THESE TOPICS SHOWS

THAT REACT ACTS AS A DEMOCRATIC AGENT FOR THIS KIND OF KNOWLEDGE IN THE FRONT-END WORLD INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR
171. None
172. ### THIS IS THE EIGHT-YEARS-AGO-ME GIVING A TALK ABOUT IONIC AT

AN IOS DEVELOPERS MEETUP TELLING THEM THAT ANGULAR WOULD BE THE FUTURE.
173. ### #6 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR

FOR DONโT ALWAYS TRUST ALL OF MY SPECULATIONS/FUTURE PREDICTIONS ๐คท

177. None