Slide 1

Slide 1 text

¡Hola, React Alicante! ✋ 🇪🇸 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR • THE 28TH OF JUNE, 2022.

Slide 2

Slide 2 text

MATHEUS ALBUQUERQUE INSIDE FIBER THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 3

Slide 3 text

I’M MATHEUS 🙋 ↝ @YTHECOMBINATOR ON THE WEB ↝ SR. SOFTWARE ENGINEER @MEDALLIA ↝ MENTOR @TECHLABS

Slide 4

Slide 4 text

Disclaimers INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 5

Slide 5 text

#1 REACT SOURCE CODE IS CONSTANTLY CHANGING, AND SOME THOUGHTS ARE SPECULATIONS INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 6

Slide 6 text

#2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR 🤯 = FURTHER DISCUSSIONS AFTER THE SESSION

Slide 7

Slide 7 text

A bit of context INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

CONTINUATIONS ALGEBRAIC EFFECTS COROUTINES FIBERS THREADS GENERATORS

Slide 10

Slide 10 text

ALGEBRAIC EFFECTS COROUTINES FIBERS GENERATORS CONTINUATIONS THREADS

Slide 11

Slide 11 text

Fiber(s) INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 12

Slide 12 text

function add(x,y) { const result = x + y; return result; } add(2, 2) STACK FRAMES

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

↝ 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

Slide 16

Slide 16 text

Fibers as Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 17

Slide 17 text

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.

Slide 18

Slide 18 text

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.

Slide 19

Slide 19 text

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.

Slide 20

Slide 20 text

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.

Slide 21

Slide 21 text

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.

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

Visualizing Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 24

Slide 24 text

#EXPERIMENT 💻 #1 Inspecting Elements

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

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; }

Slide 28

Slide 28 text

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; } 🤯

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Manipulating Units of Work INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 33

Slide 33 text

#QUESTION 🤔 Have you ever heard about homoiconicity?

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

(let [x 1] (inc x)) ; = > 2 HOMOICONICITY PERFORMS A TEMPORARY BINDING (BINDS X TO THE VALUE 1)

Slide 36

Slide 36 text

INCREMENTS X TO GIVE THE RETURN VALUE OF 2 (let [x 1] (inc x)) ; = > 2 HOMOICONICITY

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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)

Slide 39

Slide 39 text

🤯 #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.”

Slide 40

Slide 40 text

↝ REACT ELEMENTS ARE JUST DATA ↝ JUST LIKE IN LISP, REACT COMPONENTS CAN MANIPULATE THEIR CHILDREN AND RETURN COMPLETELY DIFFERENT THINGS HOMOICONICITY

Slide 41

Slide 41 text

#EXPERIMENT 💻 #2 Pattern Matching in React

Slide 42

Slide 42 text

PATTERN MATCHING

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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 ( ); } PATTERN MATCHING

Slide 45

Slide 45 text

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 ( ); } PATTERN MATCHING + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE COMPONENT BUNDLE THAT MATCHES

Slide 46

Slide 46 text

const supportsSensor + REACT.SUSPENSE + REACT.LAZY() = USERS DOWNLOAD ONLY THE COMPONENT BUNDLE THAT MATCHES MANIPULATING BASED ON ELEMENTS DATA.

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

Fibers out there INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 49

Slide 49 text

↝ 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

Slide 50

Slide 50 text

Coroutines INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

#1 A GENERATOR (PRODUCER) THAT CAN ALSO CONSUME VALUES. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 53

Slide 53 text

#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.

Slide 54

Slide 54 text

#2 A GENERATOR THAT CAN RESOLVE ASYNCHRONOUS VALUES, LIKE ASYNC/AWAIT. INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 55

Slide 55 text

#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.

Slide 56

Slide 56 text

#3 A GENERATOR THAT CAN YIELD WITH A STACKFUL CONTINUATION INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 57

Slide 57 text

#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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

Coroutines & React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 61

Slide 61 text

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.

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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.

Slide 64

Slide 64 text

Coroutines & Concurrent React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

{result}

; }

Slide 68

Slide 68 text

#EXPERIMENT 💻 #3 Building a coroutines-based scheduler

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

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

{result}

; }

Slide 72

Slide 72 text

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

{result}

; }

Slide 73

Slide 73 text

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

{result}

; } PROMOTED TO A GENERATOR YIELDING EXECUTION DOING CONCURRENT TASKS

Slide 74

Slide 74 text

DEEP DIVING ON CONCURRENT REACT

Slide 75

Slide 75 text

enum SchedulerState { IDLE = "IDLE", PENDING = "PENDING", DONE = "DONE", } class Scheduler { 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; } } }

Slide 76

Slide 76 text

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; } }

Slide 77

Slide 77 text

DID WE JUST useTransition’ED? 🤔

Slide 78

Slide 78 text

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

{result}

; }

Slide 79

Slide 79 text

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

{result}

; }

Slide 80

Slide 80 text

YES, WE DID 🤓 WITH OUR OWN, COROUTINES-BASED, SCHEDULER

Slide 81

Slide 81 text

↝ 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

Slide 82

Slide 82 text

↝ ↓ ORIGINAL RENDER TASK USER INPUT → ↑ HIGHER PRIORITY RENDER TASK ↓ RESUME ORIGINAL RENDER TASK

Slide 83

Slide 83 text

↝ 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

Slide 84

Slide 84 text

Coroutines out there INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 85

Slide 85 text

↝ 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

Slide 86

Slide 86 text

↝ 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

Slide 87

Slide 87 text

No content

Slide 88

Slide 88 text

↝ 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

Slide 89

Slide 89 text

↝ 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

Slide 90

Slide 90 text

↝ 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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

Continuations INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 94

Slide 94 text

CONTINUATIONS

Slide 95

Slide 95 text

CONTINUATIONS ↝ A CONTINUATION IS A CONTROL FLOW PRIMITIVE. ↝ IT’S AN ABSTRACTION THAT REPRESENTS THE REMAINING STEPS IN A COMPUTATION.

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

function performWork(deadline) { while (tasks.length > 0) { const task = tasks.shift(); doTask(task); if ( tasks.length > 0 & & !deadline.didTimeout & & deadline.timeRemaining() < = 0 ) { return performWork; } } } scheduleWork(performWork); CONTINUATIONS IN REACT

Slide 98

Slide 98 text

↝ 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

Slide 99

Slide 99 text

CONTINUATIONS ON THE WEB

Slide 100

Slide 100 text

CONTINUATIONS ON THE WEB async function doWork() { while (true) { let hasMoreWork = doSomeWork(); if (!hasMoreWork) { return; } if (!navigator.scheduling.isInputPending()) { continue; } await scheduler.yield(); } } 🤯

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

Effect Handlers INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 103

Slide 103 text

↝ EFFECTS ASK THE CALLING ENVIRONMENT TO HANDLE A PARTICULAR TASK ↝ WHEN AN EFFECT IS USED, THE NEAREST EFFECT HANDLER IS CALLED, WHICH ALLOWS YOU TO RUN CODE IN RESPONSE TO THE EFFECT AND RETURN SOME VALUE EFFECT HANDLERS 🤯

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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'; } }

Slide 106

Slide 106 text

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'; } }

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

Effect handlers in React INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR

Slide 109

Slide 109 text

#1 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR LAYOUT ALGORITHM

Slide 110

Slide 110 text

THE REACT TEAM APPARENTLY SPENT SOME TIME EXPERIMENTING WITH EFFECT- HANDLER CONTROL STRUCTURES FOR MANAGING LAYOUT

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

#2 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR CONTEXT API DRAFTS

Slide 113

Slide 113 text

THEY’VE ALSO REMODELED THE CONTEXT API USING ALGEBRAIC EFFECTS

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

#3 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR SIDE EFFECTS WITHIN A COMPONENT

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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) ); }

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

#4 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR HOOKS API DRAFTS

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

SEBASTIAN POINTS THAT “CONCEPTUALLY, HOOKS ARE ALGEBRAIC EFFECTS”.

Slide 122

Slide 122 text

#5 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR SUSPENSE INTERNALS

Slide 123

Slide 123 text

#QUESTION 🤔 Have you ever built any suspense- ready API?

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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.

Slide 127

Slide 127 text

INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR Closing Notes

Slide 128

Slide 128 text

#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

Slide 129

Slide 129 text

#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

Slide 130

Slide 130 text

#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

Slide 131

Slide 131 text

#3 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

Slide 132

Slide 132 text

No content

Slide 133

Slide 133 text

#4 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

Slide 134

Slide 134 text

No content

Slide 135

Slide 135 text

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.

Slide 136

Slide 136 text

#5 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR DON’T ALWAYS TRUST ALL OF MY SPECULATIONS/FUTURE PREDICTIONS 🤷

Slide 137

Slide 137 text

We’re hiring! 🗺 Mostly in… 🇺🇸🇲🇽🇦🇷🇺🇾🇪🇸🇨🇿🇮🇱🇮🇳

Slide 138

Slide 138 text

🤝 🇪🇸 🤗

Slide 139

Slide 139 text

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

Slide 140

Slide 140 text

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

Slide 141

Slide 141 text

No content

Slide 142

Slide 142 text

MATHEUS ALBUQUERQUE THAT’S ALL, FOLKS! THANKS! QUESTIONS?