Railway Oriented TypeScript

A presentation at Heapcon 2022 in November 2022 in Belgrade, Serbia by Robin Pokorny

Slide 1

Slide 1

Railway Oriented TypeScript Robin Pokorny

Slide 2

Slide 2

Heapcon Typescript Functional Programming Heapcon 2022 is over, Welcome to the slides! If you’re reading this my talk is over. I welcome any feedback, questions, These are the slides that you can or comments! look at if you’d like to refresh your memory. So glad you are here. Let’s keep in touch. You can nd all my social pro les as well as my Of course, static slides are not going email on my homepage: to replace being there, so please https://robinpokorny.com. keep that in mind. During my talk, I do some live coding. The result of that is here: https://gist.github.com/robinpokorny/ fi fi 7bcde83da63463979e4916aa992192e4 Happy exploring! Robin

Slide 3

Slide 3

Example A Simple Response To A Request Happy-Path Code What if data is not valid? const action = (req, res) 1 validate(req); { const newData = updateDB(req.body); 2 log(newData); 3 return res.send(newData); }; > 3 = What if log fails? What if the DB is unreachable?

Slide 4

Slide 4

Functional Programming Don’t leave! 4

Slide 5

Slide 5

Monad Semigroup Category Sum type Functor Foldable

Slide 6

Slide 6

Erlang Haskell I ❤ FP Closure

Slide 7

Slide 7

Next 30 minutes 1 2 3 Show TypeScript Code Don’t tell But, why? Yes, really 7

Slide 8

Slide 8

Scott Wlaschin Railway Oriented Programming 8

Slide 9

Slide 9

””“”” “”“”“”“”“” ” “”“”“”“” “”“”“”“” “”“”“”“”” “” “”“”“”” “” “”“”“”“”“”“” “” “”” “”” “”“”” “”“”” “”“”“”“”“”“”“” “”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“” “”“”“”“”” “”“”“”“”” “”“”“” “”“”“”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“” “”” “”“”” “”“”“” “”“”“”“” ” “” “” ” “”“”” “”“”” ” “”“”“”“”“”” “”“”” “”“” ” “”“”“”“” “”“”“”“”“”” ” “”“”“”“” “”” “”“”“” “”” “”“”“”“”” “”” “” “”“”“”” “”“”“”” “”“” “”“”“”“”” “”“”” “”“”“”“”“” “”“”” “”“”“” “”” “”“” “”“”“” “”“”“”” “”“”“”“”“”“”“”” “”“”“” “” ” “”“”“”“”“”“”“”“”“” ” “”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”” “”“” “” ” “”“”“”“”“”“”“”” “” “”“”“”“” “”“”” “”“” “”” “”“”“”“”“”“”” “” ” “”“”“”“”“”“”“” “” “”“”“”“”“”” “”” “”“”“”“”“” ” “”“”“”“”“”“”“”“”“”“”” “”“”“” “”“”“”“”“”“”“”” “”” ” “”“” ” “”“”“”“”“”“”“”“”“”“”“”“”“” “”“”” “”“” “”“”“”“”“”“”” ” “” “”“”“” “”” “” “” “” “” “”“”“” ” “”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” ” “”“”” “”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”” “”“” “” ” “”“”“”“”“”” “” “”“”“”” “”“”“”“”“”” “”” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “”“”“”“”“”“”” “” “” 9

Slide 10

Slide 10

🍏 🍌 Function Apple -> Banana 10

Slide 11

Slide 11

🍏 🍌 🍌 🍏 🍓 🍓 11

Slide 12

Slide 12

const action = (req, res) validate(req); { const newData = updateDB(req.body); log(newData); return res.send(newData); const action = (req, res) { const { value, error } = validate(req); if (error null) { return res .status(400) .send(“Invalid request”); } 💥 let newData; }; try { newData = updateDB(req.body); } catch (e) { log(e) return res .status(500) .send(“Something went wrong 🤷”); } 💥 💥 try { log(newData); } catch (e) { Just log the logging error log(e) } return res.send(newData);

=

= ! / / }; 12

Slide 13

Slide 13

””“”” “”“”“”“”“” ” “”“”“”“” “”“”“”“” “”“”“”“”” “” “”“”“”” “” “”“”“”“”“”“” “” “”” “”” “”“”” “”“”” “”“”“”“”“”“”“” “”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“” “”“”“”“”” “”“”“”“”” “”“”“” “”“”“”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“” “”” “”“”” “”“”“” “”“”“”“” ” “” “” ” “”“”” “”“”” ” “”“”“”“”“”” “”“”” “”“” ” “”“”“”“” “”“”“”“”“”” ” “”“”“”“” “”” “”“”“” “”” “”“”“”“”” “”” “” “”“”“”” “”“”“”” “”“” “”“”“”“”” “”“”” “”“”“”“”“” “”“”” “”“”“” “”” “”“” “”“”“” “”“”“”” “”“”“”“”“”“”“”” “”“”“” “” ” “”“”“”“”“”“”“”“”“” ” “”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”” “”“” “” ” “”“”“”“”“”“”“”” “” “”“”“”“” “”“”” “”“” “”” “”“”“”“”“”“”” “” ” “”“”“”“”“”“”“” “” “”“”“”“”“”” “”” “”“”“”“”“” ” “”“”“”“”“”“”“”“”“”“”” “”“”“” “”“”“”“”“”“”“”” “”” ” “”“” ” “”“”“”“”“”“”“”“”“”“”“”“”“” “”“”” “”“” “”“”“”“”“”“”” ” “” “”“”“” “”” “” “” “” “” “”“”“” ” “”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” ” “”“”” “”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”” “”“” “” ” “”“”“”“”“”” “” “”“”“”” “”“”“”“”“”” “”” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “”“”“”“”“”“”” “” “” 13

Slide 14

Slide 14

Slide 15

Slide 15

Input Success Failure 15

Slide 16

Slide 16

Success DB g Lo e te da up at id al V Failure 16

Slide 17

Slide 17

Demo “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” “” |””“”“”“” “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” |””“”“”“”“”“”“”“” |””“”“”“”“”“”” |””“”“”“” | |””“”“”“” | |””“”“”“”“”“”“”“”“”“” | |””“”“”“”“”“”“”“”” | |””“”“”“”“”“”“”” |””“”“”“”“”“”” |””“”“”“” |””“”“”“”“”” |””“” | |””“”“”“”“” | |””“”“”“”“” |””“”“”“”“” |””“”“”“”“”“”” |””“”” | |””“”“”“”” | |””“”“”“”“”“” | |””“”“”“” “” 17

Slide 18

Slide 18

YAGNI…? You Ain’t Gonna Need It… ? 18

Slide 19

Slide 19

Typescript Self-Documenting Code Exhaustive Failure Checking Composing Can Be Tricky 19

Slide 20

Slide 20

Success DB g Lo e te da up at id al V Failure 20

Slide 21

Slide 21

Input Success Also input? Failure 21

Slide 22

Slide 22

Bypass 22

Slide 23

Slide 23

Demo “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” “” |””“”“”“” “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” |””“”“”“”“”“”“”“” |””“”“”“”“”“”” |””“”“”“” | |””“”“”“” | |””“”“”“”“”“”“”“”“”“” | |””“”“”“”“”“”“”“”” | |””“”“”“”“”“”“”” |””“”“”“”“”“”” |””“”“”“” |””“”“”“”“”” |””“” | |””“”“”“”“” | |””“”“”“”“” |””“”“”“”“” |””“”“”“”“”“”” |””“”” | |””“”“”“”” | |””“”“”“”“”“” | |””“”“”“” “” 23

Slide 24

Slide 24

Promise.resolve() YAGNI…? You Ain’t Gonna Need It… ? 24

Slide 25

Slide 25

Promises Limited API 25

Slide 26

Slide 26

Promises API Methods Combinators Promise#then Promise.race Promise#catch Promise.allSettled Promise# nally Promise.all Promise.any fi 26

Slide 27

Slide 27

Promises Limited API Domain ✖ Panic 27

Slide 28

Slide 28

Errors Domain Expected Panic Unhandleable t s u ha x E o N s k c e h c e v i INVALID INPUT DATA OUT OF MEMORY EXTERNAL SYSTEM UNREACHABLE DIVIDE BY ZERO 28

Slide 29

Slide 29

Demo “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” “” |””“”“”“” “”“”“” ” “”“”“” “”“”” “”“”“”“”“”“”“”“”“” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “!”“”“”“”“”“”“”“”“”“”“”” “” ” “”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”” “”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“” “”“”“”“”“”“”“”“” “”“”“”“” “” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “” |””“”“”“”“”“”“”“” |””“”“”“”“”“”” |””“”“”“” | |””“”“”“” | |””“”“”“”“”“”“”“”“”“” | |””“”“”“”“”“”“”“”” | |””“”“”“”“”“”“”” |””“”“”“”“”“”” |””“”“”“” |””“”“”“”“”” |””“” | |””“”“”“”“” | |””“”“”“”“” |””“”“”“”“” |””“”“”“”“”“”” |””“”” | |””“”“”“”” | |””“”“”“”“”“” | |””“”“”“” “” 29

Slide 30

Slide 30

Fp-ts https://github.com/gcanti/fp-ts 30

Slide 31

Slide 31

””“”” “”“”“”“”“” ” “”“”“”“” “”“”“”“” “”“”“”“”” “” “”“”“”” “” “”“”“”“”“”“” “” “”” “”” “”“”” “”“”” “”“”“”“”“”“”“” “”“”“” “”“”“”“”“”“”“”” “”“”“”“”“”“”“” “”“”“”“”” “”“”“”“”” “”“”“” “”“”“”“”“”“”“” “”“”“”“”“”“”“”” “”“”“”“”“” “”” Left “”“”” “”“”“” “”“”“”“” ” “” “” ” “”“”” “”“”” ” “”“”“”“”“”” “”“”” “”“” ” “”“”“”“” “”“”“”“”“”” ” “”“”“”“” “”” “”“”“” “”” “”“”“”“”” “”” “” “”“”“”” “”“”“”” “”“” “”“”“”“”” “”“”” “”“”“”“”“” “”“”” “”“”“” “”” “”“” “”“”“” “”“”“”” “”“”“”“”“”“”“”” “”“”“” “” ” “”“”“”“”“”“”“”“”“” ” “”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”” “”“” “” ” “”“”“”“”“”“”“”” “” “”“”“”“” “”“”” “”“” “”” “”“”“”“”“”“”” “” ” “”“”“”“”“”“”“” “” “”“”“”“”“”” “”” “”“”“”“”“” ” “”“”“”“”“”“”“”“”“”“”” “”“”“” “”“”“”“”“”“”“”” “”” ” “”“” ” “”“”“”“”“”“”“”“”“”“”“”“”“” “”“”” “”“” “”“”“”“”“”“”” ” “” “”“”“” “”” “” “” “” “” “”“”“” ” “”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”” ” “”“”” “”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”“”“”” “” “”“”“”“”“”“”“”” “”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”” “” “”“”“”“”“”“”“” “”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“”“” “”“”“”“”“”” “”“” “” ” “”“”“”“”“”” “” “”“”“”” “”“”“”“”“”” “”” “”“”“”“”“”“”“”“”“”“”” “”“”“”“”“”“”“”“”“”“”“”“”“” “” “”“”“”” “”“”“”“”“”“”” “” “” Right Either<S, T> = | Left<S> | Right<T> Result<T, S> = | Success<T> | Failure<S> Failure Success 31

Slide 32

Slide 32

32

Slide 33

Slide 33

Aleksandr Morozov @morozov_dev When your code works, but you have no idea how 2:05 AM · Nov 3, 2022 33

Slide 34

Slide 34

34

Slide 35

Slide 35

“You Have To Master A New Skill, But You’re Avoiding It Because You Know You’ll Be Bad At It When You First Do It.”

  • Innovation Is Combination — Greg Satell 35

Slide 36

Slide 36

Railway Oriented TypeScript @robinpokorny

Slide 37

Slide 37