Slide 1

Slide 1 text

PROGRAMMATION FONCTIONNELLE EN JAVASCRIPT ❤ Speaker : Philippe Charrière 1 ! @k33g @k33g_org ! @GitHub

Slide 2

Slide 2 text

Pourquoi ce talk?

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

Slide 5

Slide 5 text

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Sondage

Slide 8

Slide 8 text

- combien de dev fonctionnels dans la salle? - qui fait du Scala? - du Erlang ou Haskell? - du Java? - du JavaScript? - autre?

Slide 9

Slide 9 text

W.I.P. > vocabulaire(s) fonctionnel(s) > implémentations incomplètes > échanges de points de vue: https:/ /github.com/k33g/stools/issues Vous n’êtes pas obligés d’être d’accord

Slide 10

Slide 10 text

0 25 50 75 100 Before AOer FP Knowledge Checks W.I.P.

Slide 11

Slide 11 text

&'

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Programmation fonctionnelle❓

Slide 14

Slide 14 text

Définition > paradigme -> function == > façon de coder (mindset) > buzz > rendre son code safe développeurs fonctionnels

Slide 15

Slide 15 text

Pourquoi en JS❓

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Nous allons voir > Rapidement: quelques “key points” > Container > Functor > Monad > Maybe > Either > Validation ⚠

Slide 18

Slide 18 text

Key points

Slide 19

Slide 19 text

Key points > imperative vs functional > pure function > function as input & output > no iteration > (im)mutability ⚠ES2015

Slide 20

Slide 20 text

samples samples/000-func-vs-imp.js samples/001-pure-func.js samples/002-func-as-input-output.js samples/003-no-iterations.js samples/004-mutability.js samples/005-immutability.js

Slide 21

Slide 21 text

Containers

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

class Container {
 constructor(x) {
 const value = x;
 Object.defineProperty(this, "value", { get: () => value })
 }
 
 static of(x) {
 return new Container(x);
 }
 
 } let bob = Container.of('Bob Morane') bob.value == 'Bob Morane'

Slide 24

Slide 24 text

Functor

Slide 25

Slide 25 text

opération

Slide 26

Slide 26 text

nouvelle valeur reste dans le bocal

Slide 27

Slide 27 text

immutabilité

Slide 28

Slide 28 text

nouvelle valeur

Slide 29

Slide 29 text

… dans un container

Slide 30

Slide 30 text

class Functor extends Container {
 constructor(x) {
 super(x);
 }
 
 static of(x) {
 return new Functor(x);
 }
 /*
 A map function: used for chaining operations on Container
 */
 map (fn) {
 //return Functor.of(fn(this.value));
 return new this.constructor(fn(this.value));
 }
 } applique fn(x) à value nouveau Functor

Slide 31

Slide 31 text

map(function) I’m a Functor!

Slide 32

Slide 32 text

samples samples/020-functor.js

Slide 33

Slide 33 text

Monad

Slide 34

Slide 34 text

map(function)

Slide 35

Slide 35 text

functor map(function) Et là …

Slide 36

Slide 36 text

samples samples/021-functor-of-functor.js

Slide 37

Slide 37 text

“aplatir” bind() <-‘attacher’

Slide 38

Slide 38 text

class Monad extends Functor {
 constructor(x) {
 super(x);
 }
 
 static of(x) {
 return new Monad(x);
 }
 /*
 map (fn) {
 return Monad.of(fn(this.value));
 }
 */
 
 /* So, I'm a monad because I have a bind method */
 bind (fn) {
 return fn(this.value);
 }
 }

Slide 39

Slide 39 text

samples samples/030-monad.js

Slide 40

Slide 40 text

map(function) I’m a Monad! bind(function)

Slide 41

Slide 41 text

Maybe

Slide 42

Slide 42 text

Pain points I’m Null! I’m Undefined!

Slide 43

Slide 43 text

Maybe None Some

Slide 44

Slide 44 text

class Maybe {
 
 static Some(x) { return new Some(x); }
 
 static None() { return new None(); }
 
 static fromNullable(x) {
 return (x !== null && x !== undefined)
 ? Maybe.Some(x)
 : Maybe.None();
 }
 
 static of(x) { return Maybe.Some(x); }
 }

Slide 45

Slide 45 text

class None extends Monad {
 constructor() { super(null) }
 // overrides Functor.map
 map() { return this; }
 // overrides Monad.map
 bind (fn) { return this.value; }
 
 getOrElse(value) {
 return value;
 }
 
 isNone() {
 return true;
 }
 isSome() {
 return false;
 }
 
 }

Slide 46

Slide 46 text

class Some extends Monad {
 constructor(x) { super(x); }
 // overrides Functor.map
 map(fn) { // ⚠ ⚠ ⚠ 
 let res = fn(this.value);
 if(res == null || res == undefined) {
 return new None()
 }
 return new Some(res);
 }
 
 getOrElse() { return this.value; }
 
 isNone() { return false; } 
 isSome() { return true;}
 }

Slide 47

Slide 47 text

Maybe.fromNullable(42) // -> == Some(42) 
 Maybe.fromNullable(null) // -> == None()
 
 Maybe.fromNullable(42).getOrElse(“Quarante-deux") // -> == 42 
 Maybe.fromNullable(null).getOrElse(“Quarante-deux") // -> == “Quarante-deux”

Slide 48

Slide 48 text

samples samples/041-maybe.js samples/042-maybe.js

Slide 49

Slide 49 text

map(function) I’m a Maybe! J’ai 2 sous types None Some bind(function)

Slide 50

Slide 50 text

Either

Slide 51

Slide 51 text

let githubCli = new GitHubClient({
 baseUri: "http://github.at.home/api/v3",
 token:process.env.TOKEN_GHE_27_K33G
 })
 
 githubCli.fetchUserRepositories({handle:”k33g"}) .then(repositories => {
 console.log(" :", repositories);
 }).catch(error => {
 console.log(" ", error.message, error);
 })
 
 githubCli.fetchOrganizationRepositories({organization:"AC ME”}) .then(repositories => {
 console.log(" :", repositories);
 }).catch(error => {
 console.log(" ", error.message, error);
 })

Slide 52

Slide 52 text

HttpException { Error: HttpException at HttpException (/Users/k33g/dev.js/stools/samples/GitHubClient.js: 8:5) at fetch.then.response (/Users/k33g/dev.js/stools/samples/ GitHubClient.js:41:15) at process._tickCallback (internal/process/next_tick.js:103:7) status: 404, statusText: 'Not Found', url: 'http://github.at.home/api/v3/orgs/AC ME/repos' } : [ { id: 40, name: 'cuckoo', full_name: 'k33g/cuckoo',

Slide 53

Slide 53 text

Either Left Right

Slide 54

Slide 54 text

class Either {
 
 static Left(x) { return new Left(x); }
 
 static Right(x) { return new Right(x); }
 
 
 static fromNullable(x) {
 return (x !== null && x !== undefined)
 ? Either.Right(x)
 : Either.Left();
 }
 
 
 static of(x) { return Either.Right(x); }
 }

Slide 55

Slide 55 text

class Left extends Functor { constructor(err) {
 super(err)
 }
 
 map() { return this; }
 
 getOrElse(value) {return value; }
 
 
 isRight() { return false; }
 isLeft() { return true; }
 
 cata(leftFn, rightFn) { return leftFn(this.value); }
 } ou Monad

Slide 56

Slide 56 text

class Right extends Functor {
 constructor(x) {
 super(x);
 }
 
 map(fn) { return new Right(fn(this.value)); }
 
 getOrElse() { return this.value; }
 
 isRight() { return true; }
 isLeft() { return false; }
 
 cata(leftFn, rightFn) { return rightFn(this.value); }
 }

Slide 57

Slide 57 text

samples samples/051-either.js samples/052-either.js

Slide 58

Slide 58 text

I’m an Either! J’ai 2 sous types Left Right cata( left function, right function ) bind(function) map(function) ou pas

Slide 59

Slide 59 text

Mais on ne trace pas toutes les erreurs

Slide 60

Slide 60 text

Validation

Slide 61

Slide 61 text

Validation FailSuccess

Slide 62

Slide 62 text

class Validation {
 
 static Success(x) { return new Success(x); }
 
 static Fail(errList) { return new Fail(errList); }
 
 static of(x) { return Validation.Success(x); }
 } subtilité

Slide 63

Slide 63 text

class Success extends Monad {
 constructor(x) {
 super(x);
 }
 
 isSuccess() { return true; }
 
 isFail() { return false; }
 
 ap(otherContainer) {
 return otherContainer instanceof Fail
 ? otherContainer
 : otherContainer.map(this.value)
 }
 
 cata(failureFn, successFn) { return successFn(this.value); }
 }

Slide 64

Slide 64 text

class Fail extends Monad {
 constructor(err) {
 super(err)
 }
 // override
 map() { return this; }
 
 isSuccess() { return false; }
 isFail() { return true; }
 
 ap(otherContainer) {
 return otherContainer instanceof Fail
 ? new Fail(this.value.concat(otherContainer.value))
 : this
 }
 
 cata(failureFn, successFn) { return failureFn(this.value); }
 
 } subtilité

Slide 65

Slide 65 text

Validation.Success(40).cata(
 error => {console.log(" ", error)},
 success => {
 console.log(" ", success)
 }
 )
 
 Validation.Fail("Oups I did it again!").cata(
 error => {console.log(" ", error)},
 success => {
 console.log(" ", success)
 }
 )

Slide 66

Slide 66 text

samples samples/061-validation.js samples/062-validation.js

Slide 67

Slide 67 text

I’m a Validation! J’ai 2 sous types Fail Success cata( failureFn function, successFn function ) ap(validation) map(function)

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

Paysage Fonctionnel côté JS

Slide 70

Slide 70 text

Quelques libs > Monet.js: https:/ /cwmyers.github.io/monet.js/ > Ramda.js: http:/ /ramdajs.com/0.21.0/index.html > Underscore: http:/ /underscorejs.org/ > Lodash: https:/ /lodash.com/ > Folktale: http:/ /folktalejs.org/ > Fantasy Land: https:/ /github.com/fantasyland

Slide 71

Slide 71 text

Ressources

Slide 72

Slide 72 text

Lectures Mostly Adequate Guide (Brian Lonsdorf): https:/ /www.gitbook.com/book/drboolean/mostly-adequate-guide/ details Functional Programming in Java (Pierre-Yves Saumont): https:/ /www.manning.com/books/functional- programming-in-java Functional Programming in JavaScript (Luis Atencio): https:/ /www.manning.com/books/functional- programming-in-javascript Functional Programming in Scala (Paul Chiusano and Rúnar Bjarnason): https:/ /www.manning.com/books/ functional-programming-in-scala Le code source de Golo: https:/ /github.com/eclipse/golo-lang/blob/master/src/main/golo/errors.golo https:/ /github.com/eclipse/golo-lang/blob/master/src/main/java/gololang/error/Result.java Les monades en PHP: http:/ /mcamuzat.github.io/blog/2015/11/11/les-monades-en-php-cest-possible-dot/ THE MARVELLOUSLY MYSTERIOUS JAVASCRIPT MAYBE MONAD: http:/ /jrsinclair.com/articles/2016/ marvellously-mysterious-javascript-maybe-monad/ \

Slide 73

Slide 73 text

Talks Gérer les erreurs avec l'aide du système de types de Scala ! (David Sferruzza): https:/ /www.youtube.com/watch?v=TwJQKrZ23Vs TDD, comme dans Type-Directed Development (Clément Delafargue): https:/ /www.youtube.com/watch?v=XhcgCF0xXRs

Slide 74

Slide 74 text

Remerciements

Slide 75

Slide 75 text

Merci > à vous > Loïc Descotte @loic_d > Julien Ponge @jponge > Yannick Loiseau @yannick_loiseau > Thierry Chantier @titimoby > Etienne Issartial | CommitStrip > Clément Delafargue @clementd > @alpesjug

Slide 76

Slide 76 text

Questions https:/ /github.com/k33g/stools/issues https://github.com/k33g/stools