- Notifications
You must be signed in to change notification settings - Fork19
🐚 Pattern matching for modern JavaScript
FGRibreau/match-when
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Finally aclear,succinct andsafe syntax to do Pattern Matching in modern JavaScript.(backstory)
- Open-Source Webhook as a Service
- Looking for a managed Keycloak IAM ?
- Charts, simple as a URL. No more server-side rendering pain, 1 url = 1 chart
The setup is pretty simple, simply require the library withmatch
andwhen
and you are ready to go!
const{match, when}=require('match-when');
or globally
require('match-when/register');// `match` and `when` are now globally available
Now let's see how we would write a factorial function:
constfact=match({[when(0)]:1,[when()]:(n)=>n*fact(n-1)});fact(10);// 3628800
Clear and simple right?
Alternatively,match(<input>, patternSpecification)
can be used to instantly perform a match:
functionfact(n){returnmatch(n,{[when(0)]:1,[when()]:(n)=>n*fact(n-1)});}fact(10);// 3628800
Note thatwhen()
is a catch-all pattern and, if used, should always be the last condition. If you forget itmatch()
will throw aMissingCatchAllPattern
exception if nothing was matched.
npm i match-when -S
match
works well with high order functions likemap
,filter
(and so on) too:
[2,4,1,2].map(match({[when(1)]:"one",[when(2)]:"two",[when()]:"many"}));// [ 'two', 'many', 'one', 'two' ]
It also works witharrays:
functionlength(list){returnmatch({[when([])]:0,[when()]:([head, ...tail])=>1+length(tail)})(list);}length([1,1,1]);// 3
Sadly JavaScript does not offer us a way to overload operators so we're stuck withwhen.or
:
functionparseArgument(arg){returnmatch({[when.or("-h","--help")]:()=>displayHelp,[when.or("-v","--version")]:()=>displayVersion,[when()]:(whatever)=>unknownArgument.bind(null,whatever)})(arg);}parseArgument(process.argv.slice(1));// displayHelp || displayVersion || (binded)unknownArgument
constprotocols=repositories.map(match({[when.and({useGit:true},{useSSH:true})]:'git+ssh:',[when.and({useGit:true},{useHTTP:true})]:'git+http:',[when.and({useGit:true},{useHTTPS:true})]:'git+https:',[when()]:'unsupported:'}))
match-when supportsregular expressions as well:
['hey.com','fg@plop.com','fg+plop@plop.com','wat'].filter(match({[when(/\S+@\S+\.\S+/)]:false,// **seems** to be a valid email (unsafe regex for doc purpose only)[when()]:true// the email could be invalid, return it}));// ['hey.com', 'wat']
[12,42,99,101].map(match({[when.range(0,41)]:'< answer',[when.range(43,100)]:'> answer',[when(42)]:'answer',[when()]:'< 0, or > 100'}));// ['< answer', 'answer', '> answer', '< 0, or > 100']
{ x1: pattern1, ..., xn: patternn }
- matches any object with property namesx1
toxn
matching patternspattern1
topatternn
, respectively. Only the own properties of the pattern are used.[pattern0, ..., patternn]
- matches any object with property names 0 to n matching patternspattern0
topatternn
, respectively./pattern/flags
- matches any values than pass the regular expression testwhen.range(low, high)
matches any number value in the range [low, high],low
andhigh
included.when.or(pattern0, ..., patternn)
- matches if atleast onepattern
matches.when.and(pattern0, ..., patternn)
- matches ifeverypattern
matches.
I will accept PR with their associated tests for the following features:
- define and implement some syntax to support wildcards
todo-list inspired by pattern-match from dherman.
*well, of course, they are not keywords but simple functions
I work atiAdvize as a Lead Developer and Architect. iAdvize is theleading real-time customer engagement platform in Europe and is used in 40 different countries. We are one of the french startup with thefastest growth and one ofthegreatest place to work inFrance.
We are looking for aNodeJS backend developer, aScala backend developer, aJavaScript frontend developer, aFull-stack Developer and aDevOps System Engineer in Paris or Nantes.Send me a tweet if you have any questions!
About
🐚 Pattern matching for modern JavaScript