Railway Oriented TypeScript Robin Pokorny

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

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?

Functional Programming Don’t leave! 4

Monad Semigroup Category Sum type Functor Foldable

Erlang Haskell I ❤ FP Closure

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

Scott Wlaschin Railway Oriented Programming 8

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

🍏 🍌 Function Apple -> Banana 10

🍏 🍌 🍌 🍏 🍓 🍓 11

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

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

Input Success Failure 15

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

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

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

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

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

Input Success Also input? Failure 21

Bypass 22

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

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

Promises Limited API 25

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

Promises Limited API Domain ✖ Panic 27

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

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

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

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

32

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

34

“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

Railway Oriented TypeScript @robinpokorny