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