🇫🇷 Pattern Matching en JavaScript avec TComb

2018-07-01

Temps de lecture: 5 minutes max

Cette semaine lors de l'excellente conférence SunnyTech à Montpellier, j'ai pu assister à un talk extrêment intéressant (et tout particulièrement bien expliqué) de Arnaud LEMAIRE sur Un système de type en Javascript.

L'objectif de ce post n'est pas de retranscrire le talk d'Arnaud (cela viendra plus tard certainement). En fait lors de sa présentation, Arnaud nous a pointé le framework JavaScript Tcomb qui permet de faire du type checking en JavaScript.

J'ai donc décidé d'y jeter un coup d'oeil, et j'y ai retrouvé quelques concepts que j'utilise en Scala ou en Kotlin (avec le fantastique framework Arrow) 👋 désolé pour les puristes si j'ose comparer du JavaScript avec du Scala ou du Kotlin 😝

Je vous laisse découvrir les possibilités de TComb en ce qui concerne le type checking.

⚠️ Ce que j'ai trouvé intéressant avec TCom, c'est que vous pouvez définir vos propres types (avec des structures) et faire du pattern matching:

Petit détournement de TComb

Très rapidement, voici comment faire une structure:

const Person = t.struct({
  name: t.String,              // required string
  age: t.Integer,              // required integer
}, 'Person');

... Et comment utiliser la méthode match pour faire du "pattern matching":

const result = t.match(1,
  t.String, () => 'a string',
  t.Number, () => 'a number'
);

Du coup j'ai fait ceci

⚠️ c'est tout à fait expérimental, c'est un "détournement"

Je me suis défini 2 types:

const t = require('tcomb');

const Failure = t.struct({
  value: t.String
}, 'Failure');

const SuccessNumber = t.struct({
  value: t.Number
}, 'SuccessNumber');

Je les utilise dans une fabuleuse ✨ fonction divide

function divide(a,b) {
  try {
    let res = a/b
    if(res==Infinity) return Failure({value:"😡 Infinity"})
    if(isNaN(res)) return Failure({value:"😡 NaN"})

    return SuccessNumber({value: res})
  } catch (error) {
    Failure({value:`😡 ${error}`})
  }
}

Et au final mon code ressemblera à ceci:

t.match(divide(4,0),
  Failure, (o) => console.log("ouch:", o.value),
  SuccessNumber, (o) => console.log("victory:",o.value)
)

t.match(divide(4,2),
  Failure, (o) => console.log("ouch:", o.value),
  SuccessNumber, (o) => console.log("victory:",o.value)
)

t.match(divide("four",2),
  Failure, (o) => console.log("ouch:", o.value),
  SuccessNumber, (o) => console.log("victory:",o.value)
)

Et j'obtiendrais ceci à l'exécution:

ouch: 😡 Infinity
victory: 2
ouch: 😡 NaN

Et voilà. C'est court, mais j'avais besoin d'un peu de contenu pour "inaugurer" 🍾 🎉 mon nouveau blog.

Last Articles

Last Updated: 05/07/2018 à 17:59:26