Slide 1

Slide 1 text

Hello, Frontmania! ✋ 🇳🇱 INSIDE FIBER: THE IN-DEPTH OVERVIEW YOU WANTED A TLDR FOR • THE 5TH OF OCTOBER, 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 🤯 = DEEP DIVE 🤿, 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 CONTINUATIONS GENERATORS THREADS

Slide 11

Slide 11 text

#QUESTION 🤔 Who here works with React?

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 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 16

Slide 16 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 17

Slide 17 text

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

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.

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.

Slide 23

Slide 23 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 24

Slide 24 text

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

Slide 25

Slide 25 text

#EXPERIMENT 💻 #1 Inspecting Elements

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

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

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 30

Slide 30 text

No content

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

#QUESTION 🤔 Have you ever heard about homoiconicity?

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

INCREMENTS X TO GIVE THE RETURN VALUE OF 2 (let [x 1] (inc x)) ; = > 2 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

Slide 39

Slide 39 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 40

Slide 40 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.” — Wikipedia

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

#EXPERIMENT 💻 #2 Pattern Matching in React

Slide 43

Slide 43 text

#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

Slide 44

Slide 44 text

factorial : : (Integral a) = > a - > a factorial 0 = 1 factorial n = n * factorial (n - 1) PATTERN MATCHING

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

PATTERN MATCHING

Slide 47

Slide 47 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 48

Slide 48 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 49

Slide 49 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 50

Slide 50 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 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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)

Slide 54

Slide 54 text

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

Slide 55

Slide 55 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 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

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

Slide 60

Slide 60 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 61

Slide 61 text

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

Slide 62

Slide 62 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 63

Slide 63 text

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

Slide 64

Slide 64 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 65

Slide 65 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 66

Slide 66 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 67

Slide 67 text

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

Slide 68

Slide 68 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 69

Slide 69 text

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

Slide 70

Slide 70 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 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 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 75

Slide 75 text

#QUESTION 🤔 How could we improve that?

Slide 76

Slide 76 text

#EXPERIMENT 💻 #3 Building a coroutines-based scheduler

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

No content

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 { value } = props; const result = resourcefulOperation(value); return

{result}

; }

Slide 80

Slide 80 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 81

Slide 81 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 82

Slide 82 text

DEEP DIVING ON CONCURRENT REACT

Slide 83

Slide 83 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 84

Slide 84 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 85

Slide 85 text

DID WE JUST useTransition’ED? 🤔

Slide 86

Slide 86 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 87

Slide 87 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 88

Slide 88 text

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

Slide 89

Slide 89 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 90

Slide 90 text

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

Slide 91

Slide 91 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 92

Slide 92 text

COROUTINES & SCHEDULING 😔 NON-PRACTICAL… ↝ FINDING PRIMES ↝ CRACKING PASSWORDS ↝ SIERPINSKI TRIANGLE

Slide 93

Slide 93 text

COROUTINES & SCHEDULING 😔 NON-PRACTICAL… ↝ RENDERING MANY DATA-POINTS ↝ RENDERING ON A ↝ PROCESSING DATA

Slide 94

Slide 94 text

COROUTINES & SCHEDULING

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

COROUTINES & SCHEDULING

Slide 98

Slide 98 text

No content

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 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 102

Slide 102 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 103

Slide 103 text

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

Slide 104

Slide 104 text

No content

Slide 105

Slide 105 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 106

Slide 106 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 107

Slide 107 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 108

Slide 108 text

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

Slide 109

Slide 109 text

No content

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

🤯 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

Slide 112

Slide 112 text

(* state.eff *) type user = string * int effect Get: user effect Set: user - > unit 🤯 EFFECT HANDLERS IN EFF

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

(* 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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

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

Slide 121

Slide 121 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 122

Slide 122 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 123

Slide 123 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 124

Slide 124 text

↝ 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

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

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

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

THEY’VE ALSO REMODELED THE CONTEXT API USING ALGEBRAIC EFFECTS

Slide 131

Slide 131 text

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

Slide 132

Slide 132 text

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

Slide 133

Slide 133 text

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

Slide 134

Slide 134 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 135

Slide 135 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 136

Slide 136 text

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

Slide 137

Slide 137 text

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

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

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

Slide 140

Slide 140 text

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

Slide 141

Slide 141 text

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

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

No content

Slide 144

Slide 144 text

No content

Slide 145

Slide 145 text

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

Slide 146

Slide 146 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 147

Slide 147 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 148

Slide 148 text

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

Slide 149

Slide 149 text

EFFECT HANDLERS OUT THERE

Slide 150

Slide 150 text

EFFECT HANDLERS OUT THERE

Slide 151

Slide 151 text

EFFECT HANDLERS OUT THERE

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

#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

Slide 154

Slide 154 text

↝ 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

Slide 155

Slide 155 text

CONTINUATIONS IN REACT

Slide 156

Slide 156 text

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

Slide 157

Slide 157 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 158

Slide 158 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 159

Slide 159 text

CONTINUATIONS ON THE WEB

Slide 160

Slide 160 text

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

Slide 161

Slide 161 text

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

Slide 162

Slide 162 text

CONTINUATIONS OUT THERE

Slide 163

Slide 163 text

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

Slide 164

Slide 164 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 165

Slide 165 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 166

Slide 166 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 167

Slide 167 text

#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

Slide 168

Slide 168 text

#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

Slide 169

Slide 169 text

No content

Slide 170

Slide 170 text

#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

Slide 171

Slide 171 text

No content

Slide 172

Slide 172 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 173

Slide 173 text

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

Slide 174

Slide 174 text

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

Slide 175

Slide 175 text

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

Slide 176

Slide 176 text

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

Slide 177

Slide 177 text

No content

Slide 178

Slide 178 text

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