Skip to content

New API for optionals #531

@pdubroy

Description

@pdubroy

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions