-
-
Notifications
You must be signed in to change notification settings - Fork 222
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 areonSome
andonNone
.