SlideShare a Scribd company logo
@FGRibreau
Implementing pattern-matching in JavaScript
@FGRibreau
Implementing pattern-matching in JavaScript
…or how to play with EcmaScript shortcoming
-1
Pattern matching ?!?
@FGRibreau
“In computer science, pattern matching is
the act of checking a given sequence of
tokens for the presence of the constituents
of some pattern.” — wikipedia
@FGRibreau
def toYesOrNo(choice: Int): String = choice match {
case 1 => "yes"
case 0 => "no"
case _ => "error"
}
def fact(n: Int): Int = n match {
case 0 => 1
case n => n * fact(n - 1)
}
Pattern Matching in Scala
@FGRibreau
let rec factorial = function
| 0 -> 1
| n -> n * factorial(n - 1);;
Pattern Matching in OCaml
0
context
@FGRibreau
Une syntaxe de pattern-matching en JS ?
Sortez l'artillerie lourde.
@FGRibreau
_.flatten(links).map(link => {
[{protocol: 'HTTP'}]: => 1,
[{protocol: 'AMQP'}]: => 2
});
It would it be awesome to use some pattern-matching there right?
@FGRibreau
SyntaxError: /Users/FG/www/iadvize-services-
orchestration-tools/src/api/src/repositoryManagers/
github.js: Unexpected token (185:32)
183 |
184 | _.flatten(links).forEach(link => {
> 185 | [{protocol: 'HTTP'}]: => 1,
| ^
186 | [{protocol: 'AMQP'}]: => 2
187 | });
188 |
... and of course it’s not JS valid syntax
1
goal
@FGRibreau
syntactically short
javascript-minded syntax
functionally-way
I wanted a pattern-matching library
2
syntax
@FGRibreau
links.map(link => {
[{protocol: 'HTTP'}]: => 1,
[{protocol: 'AMQP'}]: => 2
});
Ok, so this is not valid,
what precisely is not valid and
how can we make it valid?
@FGRibreau
links.map(link => {
[{protocol: 'HTTP'}]: () => 1,
[{protocol: ‘AMQP'}]: () => 2
});
links.map(link => {
[{protocol: 'HTTP'}]: 1,
[{protocol: ‘AMQP'}]: 2
});
links.map(link => {
[{protocol: 'HTTP'}]: => 1,
[{protocol: 'AMQP'}]: => 2
});
@FGRibreau
{
[{protocol: ‘HTTP'}]: 1,
[{protocol: ‘AMQP’}]: 2
}
The rest is syntactically valid
ES6 "computed property names"
{
[{protocol: ‘HTTP’}]: () => 1,
[{protocol: ‘AMQP’}]: () => 2
}
@FGRibreau
links.map(link => {})
[undefined, undefined]
links.map(link => {1})
[undefined, undefined]
links.map(link => {return 1})
[1,1]
links.map(link => 1)
[1,1]
Syntactically valid, semantically invalid
… but then I won't have my pattern matching.
@FGRibreau
BUT…
@FGRibreau
If I go from there…
_.flatten(links).map(link => {
[{protocol: 'HTTP'}]: => 1,
[{protocol: 'AMQP'}]: => 2
});
@FGRibreau
If I go from there…
_.flatten(links).map(link => {
[{protocol: 'HTTP'}]: => 1,
[{protocol: 'AMQP'}]: => 2
});
_.flatten(links).map(match({
[{protocol: 'HTTP'}]: 1,
[{protocol: 'AMQP'}]: 2
}));
…to there…
@FGRibreau
… then it’s syntactically correct!
_.flatten(links).map(match({
[{protocol: 'HTTP'}]: 1,
[{protocol: 'AMQP'}]: 2
}));
@FGRibreau
… then it’s syntactically correct!
_.flatten(links).map(match({
[{protocol: 'HTTP'}]: 1,
[{protocol: 'AMQP'}]: 2
}));
@FGRibreau
… would be great too !
const linkNumber = match(link,{
[{protocol: 'HTTP'}]: 1,
[{protocol: 'AMQP'}]: 2
});
3
Semantic
@FGRibreau
{
[{protocol: ‘HTTP'}]: 1,
[{protocol: ‘AMQP’}]: 2
}
ES6 "computed property names"
“The object initializer syntax also supports computed property names.
That allows you to put an expression in brackets [], that will be computed as
the property name.”
@FGRibreau
{
'[object Object]': 2
}
evaluates to
ES6 "computed property names"
{
[{protocol: 'HTTP'}]: 1,
[{protocol: 'AMQP'}]: 2
}
plz fix this
plz fix this
@FGRibreau
evaluates to
ES6 "computed property names"
{
[when({protocol: ‘HTTP’})]: 1,
[when({protocol: ‘AMQP'})]: 2,
[when()]: 0,
}
{
'{"protocol":"HTTP"}': 1,
'{"protocol":"AMQP"}': 2,
Symbol('match.pattern.catchAll'): 0
}
@FGRibreau
evaluates to
ES6 "computed property names"
{
[when({protocol: ‘HTTP’})]: 1,
[when({protocol: ‘AMQP'})]: 2,
[when()]: 0,
}
{
'{"protocol":"HTTP"}': 1,
'{"protocol":"AMQP"}': 2,
Symbol('match.pattern.catchAll'): 0
}
@FGRibreau
ES6 "computed property names"
{
[when({protocol: ‘HTTP’})]: 1,
[when({protocol: ‘AMQP'})]: 2,
[when()]: 0,
}
{
'{"protocol":"HTTP"}': 1,
'{"protocol":"AMQP"}': 2,
Symbol('match.pattern.catchAll'): 0
}
function when(props){
if(props === undefined){
return _catchAllSymbol;
}
return _JSON.stringify(props);
}
@FGRibreau
Order is lost by match’s object
.map(match({
[when.range(0, 43)]: 42,
[when(42)]: 72
}))
when.range(0,43) => '["Symbol(match.pattern.RANGE)",0,43]'
when(42) => '[42]'
JS objects are an unordered collection of properties
@FGRibreau
Fixing properties declaration
?
.map(match({
[when.range(0, 43)]: 42,
[when(42)]: 72
}))
.map(match(new Map([
[ when.range(0, 43), 42 ],
[ when(42), 72 ],
[ when(), 'never should be hit' ]
])))
NO!
@FGRibreau
Fixing properties declaration
?
.map(match({
[when.range(0, 43)]: 42,
[when(42)]: 72
}))
.map(match([
[ when.range(0, 43), 42 ],
[ when(42), 72 ],
[ when(), 'never should be hit' ]
]))
NO!
plz fix this
plz fix this
@FGRibreau
Fixing properties declaration
.map(match({
[when.range(0, 43)]: 42,
[when(42)]: 72
}))
- same callsite
- single thread
- sequential evaluation
@FGRibreau
Fixing properties declaration
.map(match({
[when.range(0, 43)]: 42,
[when(42)]: 72
}))
- same callsite
- single thread
- sequential evaluation
@FGRibreau
Fixing properties declaration
when.range(0,43) => '[0, "Symbol(match.pattern.RANGE)",0,43]'
when(42) => '[1, 42]'
… #problemSolved …
.map(match({
[when.range(0, 43)]: 42,
[when(42)]: 72
}))
- same callsite
- single thread
- sequential evaluation
@FGRibreau
How to get matched value?
const fact = match({
[when(0)]: 1,
[when()]: n * fact(n-1)
});
fact(10);
n is not defined
@FGRibreau
How to get matched value?
const fact = match({
[when(0)]: 1,
[when()]: n * fact(n-1)
});
fact(10);
simple, use a function:
const fact = match({
[when(0)]: 1,
[when()]: (n) => n * fact(n-1)
});
fact(10); // 3628800
@FGRibreau
How to get matched value?
const fact = match({
[when(0)]: 1,
[when()]: n * fact(n-1)
});
fact(10);
simple, use a function:
const fact = match({
[when(0)]: 1,
[when()]: (n) => n * fact(n-1)
});
fact(10); // 3628800
@FGRibreau
const input = [{protocol: 'HTTP', i:10}, {protocol: 'AMQP', i:11},
{protocol: 'WAT', i:3}];
const output = input.map(match({
[when({protocol:'HTTP'})]: (i) => () => 1,
[when({protocol:'AMQP'})]: (i) => () => 2,
[when()]: (i) => () => 0,
}));
output.map((f) => f()) // => [1, 2, 20]
But how do I yield functions?
4
implementation
@FGRibreau
function match(/* args... */){
const args = Array.from(arguments),
obj = args[args.length-1];
// pre-compute matchers
let matchers = [];
for(let key in obj){
matchers.push(when.unserialize(key, obj[key])); // e.g. {match:(mixed)=>boolean,result:mixed,position:number}
}
matchers.sort(function(a, b){
return a.position < b.position ? -1 : 1;
});
if(Object.getOwnPropertySymbols(obj).indexOf(_catchAllSymbol) !== -1){
matchers.push(when.unserialize(_catchAllSymbol, obj[_catchAllSymbol]));
}
const calculateResult = function(input){
const matched = matchers.find((matcher) => matcher.match(input));
if (!matched) {
throw new MissingCatchAllPattern();
}
return typeof matched.result === 'function' ? matched.result(input) : matched.result;
};
return args.length === 2 ? calculateResult(args[0]) : calculateResult;
}
@FGRibreau
when.unserialize = function(serializedKey, value){
if(serializedKey === _catchAllSymbol){
return {
match: _true, // same as: () => true
result: value,
position: Infinity
};
}
const {position, matcherConfiguration} = _unserialize(serializedKey);
return {
match: _match(matcherConfiguration),
result: value,
position: position
};
};
@FGRibreau
function _match(props){ // [{type}, …]
if(Array.isArray(props)){
if(props[0] === _patternORStr){ // _patternORStr = Symbol(‘OR’)
props.shift();
return function(input){
return props[0].some((prop) => _matching(prop, input));
};
}
if(props[0] === _patternANDStr){ // _patternANDStr = Symbol(‘AND’)
props.shift();
return function(input){
return props[0].every((prop) => _matching(prop, input));
};
}
if(props[0] === _patternRANGEStr){ // _patternRANGEStr = Symbol(‘RANGE’)
props.shift();
return function(input){
return props[0] <= input && input <= props[1];
};
}
}
function _matching(props, input){
// [...]
if(props instanceof RegExp){
return props.test(input);
}
if(typeof input === 'object'){
for(let prop in props){
if(input.hasOwnProperty(prop) && input[prop] !== props[prop]){
return false;
}
}
return true;
}
return props === input;
}
return (input) => _matching(props, input);
}
5
wrap up
@FGRibreau
@FGRibreau
6
Next step
@FGRibreau
function replaceInstanceId(elem) {
if (_.isPlainObject(elem)) {
return _.mapValues(elem, replaceInstanceId);
} else if (_.isArray(elem)) {
return _.map(elem, replaceInstanceId);
} else if (_.isString(elem) && _.includes(elem, 'instance_id')) {
return _.template(elem)({instance_id: conf.instance_id});
}
return elem;
}
Type Matching
const replaceInstanceId = match({
[when(Object)]:(elem) => _.mapValues(elem, replaceInstanceId),
[when(Array)]:(elem) => _.map(elem, replaceInstanceId),
[when.and(String, /instance_id/)]: (elem) => _.template(elem)({instance_id:
conf.instance_id}),
[when()]: _.identity
});
With type matching
@FGRibreau
const replaceInstanceId = match({
// extraction
[when({a:when._, b:when._, c:{e:when._})]:(a, b, e) => {a, b, e},
[when(Array)]:(elem) => _.map(elem, replaceInstanceId),
[when()]: _.identity
});
Pattern Extraction
@FGRibreau
@FGRibreau
François-Guillaume
RIBREAU
@FGRibreau
Tightly crafted developer oriented
online real-time monitoring and
administration service for Redis.
Join us
Frontend Dev - Backend Dev
Fullstack Dev - DevOps
#scala #nodejs #react #docker #xmpp

More Related Content

What's hot

Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
José Paumard
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
Stephen Vance
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptIngvar Stepanyan
 
Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
Jamund Ferguson
 
JavaScript on the GPU
JavaScript on the GPUJavaScript on the GPU
JavaScript on the GPU
Jarred Nicholls
 
C++ Programs
C++ ProgramsC++ Programs
C++ Programs
NarayanlalMenariya
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
José Paumard
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
boyney123
 
Argon walkthru 1-26
Argon walkthru 1-26Argon walkthru 1-26
Argon walkthru 1-26
Nachiketas Ramanujam
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate Busters
HamletDRC
 
Java 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven editionJava 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven editionJosé Paumard
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
Manoj Kumar
 
Virtual Machine Constructions for Dummies
Virtual Machine Constructions for DummiesVirtual Machine Constructions for Dummies
Virtual Machine Constructions for Dummies
National Cheng Kung University
 
JDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJosé Paumard
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
David de Boer
 
Exploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your pluginsExploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your pluginsMarian Marinov
 
From Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOSFrom Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOS
Susan Potter
 
What's New in ES6 for Web Devs
What's New in ES6 for Web DevsWhat's New in ES6 for Web Devs
What's New in ES6 for Web Devs
Rami Sayar
 
Java Full Throttle
Java Full ThrottleJava Full Throttle
Java Full Throttle
José Paumard
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
Colin DeCarlo
 

What's hot (20)

Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
 
JavaScript on the GPU
JavaScript on the GPUJavaScript on the GPU
JavaScript on the GPU
 
C++ Programs
C++ ProgramsC++ Programs
C++ Programs
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
 
Argon walkthru 1-26
Argon walkthru 1-26Argon walkthru 1-26
Argon walkthru 1-26
 
Java Boilerplate Busters
Java Boilerplate BustersJava Boilerplate Busters
Java Boilerplate Busters
 
Java 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven editionJava 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven edition
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
Virtual Machine Constructions for Dummies
Virtual Machine Constructions for DummiesVirtual Machine Constructions for Dummies
Virtual Machine Constructions for Dummies
 
JDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easy
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
Exploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your pluginsExploiting the newer perl to improve your plugins
Exploiting the newer perl to improve your plugins
 
From Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOSFrom Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOS
 
What's New in ES6 for Web Devs
What's New in ES6 for Web DevsWhat's New in ES6 for Web Devs
What's New in ES6 for Web Devs
 
Java Full Throttle
Java Full ThrottleJava Full Throttle
Java Full Throttle
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 

Similar to Implementing pattern-matching in JavaScript (full version)

The Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationThe Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationNorman Richards
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
David Furber
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function Programming
Istanbul Tech Talks
 
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
Pamela Fox
 
GeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheetGeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheet
Jose Perez
 
Scala @ TomTom
Scala @ TomTomScala @ TomTom
Scala @ TomTom
Eric Bowman
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
Domenic Denicola
 
Javascript
JavascriptJavascript
Javascript
Vlad Ifrim
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
Sean Cribbs
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
niklal
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
HamletDRC
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
AngularJS Testing
AngularJS TestingAngularJS Testing
AngularJS Testing
Eyal Vardi
 
PHP Static Code Review
PHP Static Code ReviewPHP Static Code Review
PHP Static Code Review
Damien Seguy
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
Sunghyouk Bae
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
Raimonds Simanovskis
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
Eduard Tomàs
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
Mite Mitreski
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 

Similar to Implementing pattern-matching in JavaScript (full version) (20)

The Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unificationThe Logical Burrito - pattern matching, term rewriting and unification
The Logical Burrito - pattern matching, term rewriting and unification
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function Programming
 
Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
 
GeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheetGeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheet
 
Short intro to ECMAScript
Short intro to ECMAScriptShort intro to ECMAScript
Short intro to ECMAScript
 
Scala @ TomTom
Scala @ TomTomScala @ TomTom
Scala @ TomTom
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Javascript
JavascriptJavascript
Javascript
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
AngularJS Testing
AngularJS TestingAngularJS Testing
AngularJS Testing
 
PHP Static Code Review
PHP Static Code ReviewPHP Static Code Review
PHP Static Code Review
 
Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017Kotlin @ Coupang Backend 2017
Kotlin @ Coupang Backend 2017
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
 
EcmaScript unchained
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 

More from François-Guillaume Ribreau

REX LEAN- Créer un SaaS et être rentable après 6 mois
REX LEAN- Créer un SaaS et être rentable après 6 moisREX LEAN- Créer un SaaS et être rentable après 6 mois
REX LEAN- Créer un SaaS et être rentable après 6 mois
François-Guillaume Ribreau
 
⛳️ Votre API passe-t-elle le contrôle technique ?
⛳️ Votre API passe-t-elle le contrôle technique ?⛳️ Votre API passe-t-elle le contrôle technique ?
⛳️ Votre API passe-t-elle le contrôle technique ?
François-Guillaume Ribreau
 
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
François-Guillaume Ribreau
 
He stopped using for/while loops, you won't believe what happened next!
He stopped using for/while loops, you won't believe what happened next!He stopped using for/while loops, you won't believe what happened next!
He stopped using for/while loops, you won't believe what happened next!
François-Guillaume Ribreau
 
Une plateforme moderne pour le groupe SIPA/Ouest-France 
Une plateforme moderne pour le groupe SIPA/Ouest-France Une plateforme moderne pour le groupe SIPA/Ouest-France 
Une plateforme moderne pour le groupe SIPA/Ouest-France 
François-Guillaume Ribreau
 
[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...
[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...
[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...
François-Guillaume Ribreau
 
[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...
[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...
[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...
François-Guillaume Ribreau
 
RedisConf 2016 - Redis usage and ecosystem
RedisConf 2016 - Redis usage and ecosystemRedisConf 2016 - Redis usage and ecosystem
RedisConf 2016 - Redis usage and ecosystem
François-Guillaume Ribreau
 
Automatic constraints as a team maturity accelerator for startups
Automatic constraints as a team maturity accelerator for startupsAutomatic constraints as a team maturity accelerator for startups
Automatic constraints as a team maturity accelerator for startups
François-Guillaume Ribreau
 
Development Principles & Philosophy
Development Principles & PhilosophyDevelopment Principles & Philosophy
Development Principles & Philosophy
François-Guillaume Ribreau
 
Les enjeux de l'information et de l'algorithmique dans notre société
Les enjeux de l'information et de l'algorithmique dans notre sociétéLes enjeux de l'information et de l'algorithmique dans notre société
Les enjeux de l'information et de l'algorithmique dans notre société
François-Guillaume Ribreau
 
How I monitor SaaS products
How I monitor SaaS productsHow I monitor SaaS products
How I monitor SaaS products
François-Guillaume Ribreau
 
Continous Integration of (JS) projects & check-build philosophy
Continous Integration of (JS) projects & check-build philosophyContinous Integration of (JS) projects & check-build philosophy
Continous Integration of (JS) projects & check-build philosophy
François-Guillaume Ribreau
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
François-Guillaume Ribreau
 
Approfondissement CSS3
Approfondissement CSS3Approfondissement CSS3
Approfondissement CSS3
François-Guillaume Ribreau
 
Découverte HTML5/CSS3
Découverte HTML5/CSS3Découverte HTML5/CSS3
Découverte HTML5/CSS3
François-Guillaume Ribreau
 

More from François-Guillaume Ribreau (16)

REX LEAN- Créer un SaaS et être rentable après 6 mois
REX LEAN- Créer un SaaS et être rentable après 6 moisREX LEAN- Créer un SaaS et être rentable après 6 mois
REX LEAN- Créer un SaaS et être rentable après 6 mois
 
⛳️ Votre API passe-t-elle le contrôle technique ?
⛳️ Votre API passe-t-elle le contrôle technique ?⛳️ Votre API passe-t-elle le contrôle technique ?
⛳️ Votre API passe-t-elle le contrôle technique ?
 
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...Choisir entre une API  RPC, SOAP, REST, GraphQL?  
Et si le problème était ai...
Choisir entre une API RPC, SOAP, REST, GraphQL? 
Et si le problème était ai...
 
He stopped using for/while loops, you won't believe what happened next!
He stopped using for/while loops, you won't believe what happened next!He stopped using for/while loops, you won't believe what happened next!
He stopped using for/while loops, you won't believe what happened next!
 
Une plateforme moderne pour le groupe SIPA/Ouest-France 
Une plateforme moderne pour le groupe SIPA/Ouest-France Une plateforme moderne pour le groupe SIPA/Ouest-France 
Une plateforme moderne pour le groupe SIPA/Ouest-France 
 
[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...
[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...
[BreizhCamp, format 15min] Construire et automatiser l'ecosystème de son Saa...
 
[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...
[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...
[BreizhCamp, format 15min] Une api rest et GraphQL sans code grâce à PostgR...
 
RedisConf 2016 - Redis usage and ecosystem
RedisConf 2016 - Redis usage and ecosystemRedisConf 2016 - Redis usage and ecosystem
RedisConf 2016 - Redis usage and ecosystem
 
Automatic constraints as a team maturity accelerator for startups
Automatic constraints as a team maturity accelerator for startupsAutomatic constraints as a team maturity accelerator for startups
Automatic constraints as a team maturity accelerator for startups
 
Development Principles & Philosophy
Development Principles & PhilosophyDevelopment Principles & Philosophy
Development Principles & Philosophy
 
Les enjeux de l'information et de l'algorithmique dans notre société
Les enjeux de l'information et de l'algorithmique dans notre sociétéLes enjeux de l'information et de l'algorithmique dans notre société
Les enjeux de l'information et de l'algorithmique dans notre société
 
How I monitor SaaS products
How I monitor SaaS productsHow I monitor SaaS products
How I monitor SaaS products
 
Continous Integration of (JS) projects & check-build philosophy
Continous Integration of (JS) projects & check-build philosophyContinous Integration of (JS) projects & check-build philosophy
Continous Integration of (JS) projects & check-build philosophy
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
Approfondissement CSS3
Approfondissement CSS3Approfondissement CSS3
Approfondissement CSS3
 
Découverte HTML5/CSS3
Découverte HTML5/CSS3Découverte HTML5/CSS3
Découverte HTML5/CSS3
 

Recently uploaded

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
Vlad Stirbu
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 

Recently uploaded (20)

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 

Implementing pattern-matching in JavaScript (full version)

  • 2. @FGRibreau Implementing pattern-matching in JavaScript …or how to play with EcmaScript shortcoming
  • 4. @FGRibreau “In computer science, pattern matching is the act of checking a given sequence of tokens for the presence of the constituents of some pattern.” — wikipedia
  • 5. @FGRibreau def toYesOrNo(choice: Int): String = choice match { case 1 => "yes" case 0 => "no" case _ => "error" } def fact(n: Int): Int = n match { case 0 => 1 case n => n * fact(n - 1) } Pattern Matching in Scala
  • 6. @FGRibreau let rec factorial = function | 0 -> 1 | n -> n * factorial(n - 1);; Pattern Matching in OCaml
  • 8. @FGRibreau Une syntaxe de pattern-matching en JS ? Sortez l'artillerie lourde.
  • 9. @FGRibreau _.flatten(links).map(link => { [{protocol: 'HTTP'}]: => 1, [{protocol: 'AMQP'}]: => 2 }); It would it be awesome to use some pattern-matching there right?
  • 10. @FGRibreau SyntaxError: /Users/FG/www/iadvize-services- orchestration-tools/src/api/src/repositoryManagers/ github.js: Unexpected token (185:32) 183 | 184 | _.flatten(links).forEach(link => { > 185 | [{protocol: 'HTTP'}]: => 1, | ^ 186 | [{protocol: 'AMQP'}]: => 2 187 | }); 188 | ... and of course it’s not JS valid syntax
  • 14. @FGRibreau links.map(link => { [{protocol: 'HTTP'}]: => 1, [{protocol: 'AMQP'}]: => 2 }); Ok, so this is not valid, what precisely is not valid and how can we make it valid?
  • 15. @FGRibreau links.map(link => { [{protocol: 'HTTP'}]: () => 1, [{protocol: ‘AMQP'}]: () => 2 }); links.map(link => { [{protocol: 'HTTP'}]: 1, [{protocol: ‘AMQP'}]: 2 }); links.map(link => { [{protocol: 'HTTP'}]: => 1, [{protocol: 'AMQP'}]: => 2 });
  • 16. @FGRibreau { [{protocol: ‘HTTP'}]: 1, [{protocol: ‘AMQP’}]: 2 } The rest is syntactically valid ES6 "computed property names" { [{protocol: ‘HTTP’}]: () => 1, [{protocol: ‘AMQP’}]: () => 2 }
  • 17. @FGRibreau links.map(link => {}) [undefined, undefined] links.map(link => {1}) [undefined, undefined] links.map(link => {return 1}) [1,1] links.map(link => 1) [1,1] Syntactically valid, semantically invalid … but then I won't have my pattern matching.
  • 19. @FGRibreau If I go from there… _.flatten(links).map(link => { [{protocol: 'HTTP'}]: => 1, [{protocol: 'AMQP'}]: => 2 });
  • 20. @FGRibreau If I go from there… _.flatten(links).map(link => { [{protocol: 'HTTP'}]: => 1, [{protocol: 'AMQP'}]: => 2 }); _.flatten(links).map(match({ [{protocol: 'HTTP'}]: 1, [{protocol: 'AMQP'}]: 2 })); …to there…
  • 21. @FGRibreau … then it’s syntactically correct! _.flatten(links).map(match({ [{protocol: 'HTTP'}]: 1, [{protocol: 'AMQP'}]: 2 }));
  • 22. @FGRibreau … then it’s syntactically correct! _.flatten(links).map(match({ [{protocol: 'HTTP'}]: 1, [{protocol: 'AMQP'}]: 2 }));
  • 23. @FGRibreau … would be great too ! const linkNumber = match(link,{ [{protocol: 'HTTP'}]: 1, [{protocol: 'AMQP'}]: 2 });
  • 25. @FGRibreau { [{protocol: ‘HTTP'}]: 1, [{protocol: ‘AMQP’}]: 2 } ES6 "computed property names" “The object initializer syntax also supports computed property names. That allows you to put an expression in brackets [], that will be computed as the property name.”
  • 26. @FGRibreau { '[object Object]': 2 } evaluates to ES6 "computed property names" { [{protocol: 'HTTP'}]: 1, [{protocol: 'AMQP'}]: 2 }
  • 29. @FGRibreau evaluates to ES6 "computed property names" { [when({protocol: ‘HTTP’})]: 1, [when({protocol: ‘AMQP'})]: 2, [when()]: 0, } { '{"protocol":"HTTP"}': 1, '{"protocol":"AMQP"}': 2, Symbol('match.pattern.catchAll'): 0 }
  • 30. @FGRibreau evaluates to ES6 "computed property names" { [when({protocol: ‘HTTP’})]: 1, [when({protocol: ‘AMQP'})]: 2, [when()]: 0, } { '{"protocol":"HTTP"}': 1, '{"protocol":"AMQP"}': 2, Symbol('match.pattern.catchAll'): 0 }
  • 31. @FGRibreau ES6 "computed property names" { [when({protocol: ‘HTTP’})]: 1, [when({protocol: ‘AMQP'})]: 2, [when()]: 0, } { '{"protocol":"HTTP"}': 1, '{"protocol":"AMQP"}': 2, Symbol('match.pattern.catchAll'): 0 } function when(props){ if(props === undefined){ return _catchAllSymbol; } return _JSON.stringify(props); }
  • 32. @FGRibreau Order is lost by match’s object .map(match({ [when.range(0, 43)]: 42, [when(42)]: 72 })) when.range(0,43) => '["Symbol(match.pattern.RANGE)",0,43]' when(42) => '[42]' JS objects are an unordered collection of properties
  • 33. @FGRibreau Fixing properties declaration ? .map(match({ [when.range(0, 43)]: 42, [when(42)]: 72 })) .map(match(new Map([ [ when.range(0, 43), 42 ], [ when(42), 72 ], [ when(), 'never should be hit' ] ]))) NO!
  • 34. @FGRibreau Fixing properties declaration ? .map(match({ [when.range(0, 43)]: 42, [when(42)]: 72 })) .map(match([ [ when.range(0, 43), 42 ], [ when(42), 72 ], [ when(), 'never should be hit' ] ])) NO!
  • 37. @FGRibreau Fixing properties declaration .map(match({ [when.range(0, 43)]: 42, [when(42)]: 72 })) - same callsite - single thread - sequential evaluation
  • 38. @FGRibreau Fixing properties declaration .map(match({ [when.range(0, 43)]: 42, [when(42)]: 72 })) - same callsite - single thread - sequential evaluation
  • 39. @FGRibreau Fixing properties declaration when.range(0,43) => '[0, "Symbol(match.pattern.RANGE)",0,43]' when(42) => '[1, 42]' … #problemSolved … .map(match({ [when.range(0, 43)]: 42, [when(42)]: 72 })) - same callsite - single thread - sequential evaluation
  • 40. @FGRibreau How to get matched value? const fact = match({ [when(0)]: 1, [when()]: n * fact(n-1) }); fact(10); n is not defined
  • 41. @FGRibreau How to get matched value? const fact = match({ [when(0)]: 1, [when()]: n * fact(n-1) }); fact(10); simple, use a function: const fact = match({ [when(0)]: 1, [when()]: (n) => n * fact(n-1) }); fact(10); // 3628800
  • 42. @FGRibreau How to get matched value? const fact = match({ [when(0)]: 1, [when()]: n * fact(n-1) }); fact(10); simple, use a function: const fact = match({ [when(0)]: 1, [when()]: (n) => n * fact(n-1) }); fact(10); // 3628800
  • 43. @FGRibreau const input = [{protocol: 'HTTP', i:10}, {protocol: 'AMQP', i:11}, {protocol: 'WAT', i:3}]; const output = input.map(match({ [when({protocol:'HTTP'})]: (i) => () => 1, [when({protocol:'AMQP'})]: (i) => () => 2, [when()]: (i) => () => 0, })); output.map((f) => f()) // => [1, 2, 20] But how do I yield functions?
  • 45. @FGRibreau function match(/* args... */){ const args = Array.from(arguments), obj = args[args.length-1]; // pre-compute matchers let matchers = []; for(let key in obj){ matchers.push(when.unserialize(key, obj[key])); // e.g. {match:(mixed)=>boolean,result:mixed,position:number} } matchers.sort(function(a, b){ return a.position < b.position ? -1 : 1; }); if(Object.getOwnPropertySymbols(obj).indexOf(_catchAllSymbol) !== -1){ matchers.push(when.unserialize(_catchAllSymbol, obj[_catchAllSymbol])); } const calculateResult = function(input){ const matched = matchers.find((matcher) => matcher.match(input)); if (!matched) { throw new MissingCatchAllPattern(); } return typeof matched.result === 'function' ? matched.result(input) : matched.result; }; return args.length === 2 ? calculateResult(args[0]) : calculateResult; }
  • 46. @FGRibreau when.unserialize = function(serializedKey, value){ if(serializedKey === _catchAllSymbol){ return { match: _true, // same as: () => true result: value, position: Infinity }; } const {position, matcherConfiguration} = _unserialize(serializedKey); return { match: _match(matcherConfiguration), result: value, position: position }; };
  • 47. @FGRibreau function _match(props){ // [{type}, …] if(Array.isArray(props)){ if(props[0] === _patternORStr){ // _patternORStr = Symbol(‘OR’) props.shift(); return function(input){ return props[0].some((prop) => _matching(prop, input)); }; } if(props[0] === _patternANDStr){ // _patternANDStr = Symbol(‘AND’) props.shift(); return function(input){ return props[0].every((prop) => _matching(prop, input)); }; } if(props[0] === _patternRANGEStr){ // _patternRANGEStr = Symbol(‘RANGE’) props.shift(); return function(input){ return props[0] <= input && input <= props[1]; }; } } function _matching(props, input){ // [...] if(props instanceof RegExp){ return props.test(input); } if(typeof input === 'object'){ for(let prop in props){ if(input.hasOwnProperty(prop) && input[prop] !== props[prop]){ return false; } } return true; } return props === input; } return (input) => _matching(props, input); }
  • 52. @FGRibreau function replaceInstanceId(elem) { if (_.isPlainObject(elem)) { return _.mapValues(elem, replaceInstanceId); } else if (_.isArray(elem)) { return _.map(elem, replaceInstanceId); } else if (_.isString(elem) && _.includes(elem, 'instance_id')) { return _.template(elem)({instance_id: conf.instance_id}); } return elem; } Type Matching const replaceInstanceId = match({ [when(Object)]:(elem) => _.mapValues(elem, replaceInstanceId), [when(Array)]:(elem) => _.map(elem, replaceInstanceId), [when.and(String, /instance_id/)]: (elem) => _.template(elem)({instance_id: conf.instance_id}), [when()]: _.identity }); With type matching
  • 53. @FGRibreau const replaceInstanceId = match({ // extraction [when({a:when._, b:when._, c:{e:when._})]:(a, b, e) => {a, b, e}, [when(Array)]:(elem) => _.map(elem, replaceInstanceId), [when()]: _.identity }); Pattern Extraction
  • 55. @FGRibreau François-Guillaume RIBREAU @FGRibreau Tightly crafted developer oriented online real-time monitoring and administration service for Redis. Join us Frontend Dev - Backend Dev Fullstack Dev - DevOps #scala #nodejs #react #docker #xmpp