implementing pattern-matching in javascript (short version)
TRANSCRIPT
@FGRibreau
Implementing pattern-matching in JavaScript…or how to play with EcmaScript shortcoming
@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
@FGRibreau
syntactically short javascript-minded syntax functionally-way
I wanted a pattern-matching library
@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
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 });
@FGRibreau
{ '[object Object]': 2 }
evaluates to
ES6 "computed property names"
{ [{protocol: 'HTTP'}]: 1, [{protocol: 'AMQP'}]: 2 }
@FGRibreau
evaluates to
ES6 "computed property names"
{ [when({protocol: ‘HTTP’})]: 1, [when({protocol: ‘AMQP'})]: 2 }
{ '{"protocol":"HTTP"}': 1, '{"protocol":"AMQP"}': 2 }
@FGRibreau
evaluates to
ES6 "computed property names"
{ [when({protocol: ‘HTTP’})]: 1, [when({protocol: ‘AMQP'})]: 2 }
{ '{"protocol":"HTTP"}': 1, '{"protocol":"AMQP"}': 2 }
@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!
@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
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