Slide 1

Slide 1 text

Gabriele Petronella Functional Programming in front-end applications Codemotion Rome . 23/03/2019

Slide 2

Slide 2 text

me, hi!

Slide 3

Slide 3 text

stuff I do

Slide 4

Slide 4 text

stuff I do

Slide 5

Slide 5 text

Does it scale?

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Scales?

Slide 8

Slide 8 text

Scaling issue #1 Fog of war

Slide 9

Slide 9 text

Scaling issue #2 Complexity

Slide 10

Slide 10 text

Complex vs Complicated

Slide 11

Slide 11 text

Complicated 4 not simple 4 stll knowable 4 usually composed by many pieces 4 can be taken apart and studied

Slide 12

Slide 12 text

Complicated

Slide 13

Slide 13 text

Complex 4 not simple 4 dense interdependencies 4 not fully knowable 4 hard to predict accurately 4 cannot be taken apart and studied

Slide 14

Slide 14 text

Complex

Slide 15

Slide 15 text

Complex (even with perfect visibility)

Slide 16

Slide 16 text

Complex Complex problems are tricker because: 4 their components behave differently depending on the global system behavior 4 adding/removing components affects the global system behavior

Slide 17

Slide 17 text

Complex system, an example

Slide 18

Slide 18 text

Complex system, another example registration.css p { font-family: "Arial"; }

Slide 19

Slide 19 text

Complex system, another example main.css p { font-family: "Reenie Beanie" !important; }

Slide 20

Slide 20 text

Addressing scalability issues

Slide 21

Slide 21 text

Issue 1: Fog of war

Slide 22

Slide 22 text

Bring in the typecheckers!

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Typechecker = Visibility A typechecker will give you visibility over the impacts of a change, allowing you to iterate faster and with more confidence. It does not replace tests, it complements them.

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Issue 2: Complexity

Slide 28

Slide 28 text

Bring in FP!

Slide 29

Slide 29 text

Functional Programming In computer science, functional programming is a programming paradigm [...] that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. -- someone on Wikipedia

Slide 30

Slide 30 text

Functional Programming, for me Everything is an expression

Slide 31

Slide 31 text

Functional Programming is boring Functional Programming patterns - Scott Wlaschin

Slide 32

Slide 32 text

In other terms...

Slide 33

Slide 33 text

Functional Programming makes problems complicated (as opposed to complex)

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Back to Earth...

Slide 36

Slide 36 text

So, should I rewrite everything in ____? (Insert language that compiles to JS)

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

Add a typechecker

Slide 39

Slide 39 text

TypeScript 4 Superset of Javascript by Microsoft 4 "pragmatic" type system with local inference 4 "progressive" type system (can have untyped parts) 4 community oriented

Slide 40

Slide 40 text

How?

Slide 41

Slide 41 text

TS migration vademecum 4 make your JS code work with a TS toolchain 4 write new features in TS 4 write definition files for your internal ecosystem 4 migrate existing JS sources to TS

Slide 42

Slide 42 text

Case study 4 50k+ LOC JS project 4 entirely ported to TS in 3 months, while actively developing features 4 internal ecosystem shared between JS and TS 4 initial port of ecosystem using definition files, then gradually rewritten

Slide 43

Slide 43 text

What about FP? Where do I start from?

Slide 44

Slide 44 text

1. Stop using null and undefined

Slide 45

Slide 45 text

1. Stop using null and undefined interface Device { getActiveCamera(): Camera | undefined; } interface Camera { getResolution(): Resolution | undefined; } interface Resolution { width: number; height: number; }

Slide 46

Slide 46 text

1. Stop using null and undefined const width = device.getActiveCamera().getResolution().width; if (width != null) { return 'No width :('; } return `Width is ${width}';

Slide 47

Slide 47 text

1. Stop using null and undefined let width = undefined; const camera = device.getActiveCamera(); if (camera != null) { const resolution = camera.getResolution(); if (resolution != null) { width = resolution.width; } } if (width != null) { return 'No width :('; } return `Width is ${width}';

Slide 48

Slide 48 text

Welcome fp-ts fp-ts is a library for typed functional programming in TypeScript https://github.com/gcanti/fp-ts

Slide 50

Slide 50 text

Example import { Option, some, none } from "fp-ts/lib/Option"; function head(arr: Array): Option { return arr.length > 0 ? some(arr[0]) : none; } head([]); // none head([1, 2]); // some(1)

Slide 51

Slide 51 text

How to work with Option map head([1, 2]).map(n => n + 100); // some(101)

Slide 54

Slide 54 text

getOrElse head([42, 43]).getOrElse(-1); // 42 head([]).getOrElse(-1); // -1

Slide 55

Slide 55 text

Let's try interface Device { getActiveCamera(): Option; } interface Camera { getResolution(): Option; } interface Resolution { width: number; height: number; }

Slide 56

Slide 56 text

Using Option device .getActiveCamera() .chain(camera => camera.getResolution()) .map(resolution => `Width is ${resolution.width}`) .getOrElse("No width :(");

Slide 58

Slide 58 text

In real life import { array } from "fp-ts/lib/Array"; array.find([1, 2, 3], x => x < 3); // some(2) array.find([1, 2, 3], x => x < 0); // none

Slide 59

Slide 59 text

2. Stop throwing exceptions

Slide 60

Slide 60 text

2. Stop throwing exceptions function validateUser(user: User): User { if (user.age >= 18) { return user; } else { throw "User is underage!"; } } validateUser(underageUser).name; // boom

Slide 62

Slide 62 text

import { Either, right, left } from "fp-ts/lib/Either"; function validateUser(user: User): Either { if (user.age >= 18) { return right(user); } else { return left("User is underage!"); } } // compile error: 'name' is not a member of 'Either' validateUser(underageUser).name;

Slide 63

Slide 63 text

Using Either Familiar? declare function doSomething(u: User): Either; validateUser(user).map(u => u.name); validateUser(user).mapLeft(e => `Error was: ${e}`); validateUser(user).chain(user => doSomething(user)); validateUser(user).getOrElse(defaultUser);

Slide 64

Slide 64 text

It's not me, it's them! import { tryCatch } from "fp-ts/lib/Either"; function safeParseJson(raw: string): Either { return tryCatch(() => JSON.parse(raw)).mapLeft(e => e.message); } JSON.parse("{}"); // {} JSON.parse("{"); // ! SyntaxError: Unexpected end of JSON input safeParseJson("{}"); // right({}) safeParseJson("{"); // left("Unexpected end of JSON input")

Slide 65

Slide 65 text

3. Stop using Promise

Slide 66

Slide 66 text

3. Stop using Promise declare function question(message: string): Promise; const answer1 = await question("What is your name?"); const answer2 = await question("What is your name?"); vs const p = question("What is your name?"); const answer1 = await p; const answer2 = await p;

Slide 68

Slide 68 text

Example declare function question(message: string): Task; const q = question("What is your name?"); const t = q.chain(answer1 => q.map(answer2 => [answer1, answer2]) ); // Task> //////////////// nothing is executing yet //////////////// t.run(); // Promise>

Slide 69

Slide 69 text

What about (typed) errors?

Slide 70

Slide 70 text

Welcome TaskEither TaskEither mixes the capabilities of Task and Either You could use Task> but TaskEither has a more convenient API.

Slide 71

Slide 71 text

Example import { TaskEither, tryCatch, taskEither, fromLeft } from "fp-ts/lib/TaskEither"; function validate(user: User): TaskEither { tryCatch(() => fetch("/myApi/validateUser", { method: "POST", body: JSON.stringify(user) }) ).chain(response => { return reponse.ok ? taskEither.of(user) : fromLeft("User is invalid"); }); }

Slide 72

Slide 72 text

Control Flow: vanilla vs FP vanilla FP optionality typeof x != null / && map/chain errors try catch map/chain async (Promise) then / catch map/chain async (async/await) try catch map/chain ... whatever else something ad-hoc map/chain

Slide 73

Slide 73 text

Resources 4 https://gcanti.github.io/fp-ts/ 4 https://github.com/MostlyAdequate/mostly- adequate-guide 4 Functional Programming Patterns 4 https://www.youtube.com/watch?v=E8I19uA-wGY 4 http://italiajs.herokuapp.com/ 4 channels #fp and #typescript

Slide 74

Slide 74 text

Thank you!

Slide 75

Slide 75 text

questions.d.ts @gabro27 https://buildo.io/careers