-
-
Notifications
You must be signed in to change notification settings - Fork 225
Description
In the next major version of Ohm, we'd like to improve the API for optionals. For example, take the following rule:
line = (key ":")? value
In the current version of Ohm (v17), you'd might write an action like this:
{
line(keyOpt, _colonOpt, value) {
const actualKey = keyOpt.childAt(0)?.sourceString ?? '<No key>';
// …
}
}Arity change
In Ohm v18, the contents of an optional node will no longer be flattened — you'll get a single node representing the entire optional. So the action will have arity 2: line(opt, value) { ... }.
Getting the values
With the above change, you could still just use childAt or children — the node would either have 0 or 2 children. But we'd like to have a nicer API for working with option nodes. Here are some of the options I'm considering:
Pattern-match style
{
line(opt, value) {
const actualKey = opt.when({
Some: (key, _colon) => key,
None: () => '<No key>'
});
// …
}
}Alternative names: caseOf, unpack. I'm avoiding match because that already has a meaning in Ohm.
Alternative key names: isSome/isNone. Might make sense to align them with methods of the same name (isSome()/isNone()).
Bare callbacks
Effectively the same thing, but without explicit case names:
{
line(opt, value) {
const actualKey = opt.getOrElse((key, _colon) => key, () => '<No key>');
// …
}
}Prior art
- The TC39 pattern matching proposal used
match/when. - patcom is a pattern-matching library for JavaScript. Also uses
match/when. - effect-ts pattern matching. Uses the same pattern-match style as above, but the method is named
match, and the keys areonSomeandonNone.