In the next major version of Ohm, we'd like to improve the API for optionals. For example, take the following rule:
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
In the next major version of Ohm, we'd like to improve the API for optionals. For example, take the following rule:
In the current version of Ohm (v17), you'd might write an action like this:
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
childAtorchildren— 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
Alternative names:
caseOf,unpack. I'm avoidingmatchbecause 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:
Prior art
match/when.match/when.match, and the keys areonSomeandonNone.