codex-storage / questionable

Elegant optional types for Nim
Other
116 stars 5 forks source link

Improve the `=?` operator #50

Closed SirNickolas closed 9 months ago

SirNickolas commented 9 months ago
  1. Accept only optional and reference types as RHS of =?.

    Motivation: I had roughly this code, simplified:

    type Id = distinct Natural
    var transitionIds: seq[?Id]
    # ...
    if id =? transitionIds[x]:
      discard # Use `id`.
    else:
      discard # Create a new object.

    After refactoring, it turned into this:

    type OptId = distinct int32 # `-1` for `none`.
    var transitionIds: seq[OptId]
    # ...
    if id =? transitionIds[x]:
      discard # Use `id`.
    else:
      discard # Create a new object.

    And… it continued to compile! The else branch suddenly became dead code.

    This commit fixes the issue. (The snippet above will produce a compilation error.)

  2. Create identifiers with genSym.

    genSym, as opposed to ident, introduces a fresh symbol, which cannot leak into user’s scope.

SirNickolas commented 9 months ago

Now I realize it requires a new template to be added to the public API of results.

https://github.com/codex-storage/questionable/blob/c2a08bd7036d1318106d2f03cfac90d4b07cc38f/questionable/results.nim#L108-L109

We also need toOption(value) that forwards to option(value). With it added, all tests pass.

Another name is needed because option from std/options has two overloads, and one of them does what we try to avoid. I don’t think it is possible to exclude a specific overload (without resorting to a macro that manipulates OpenSymChoice/ClosedSymChoice, but that’s clearly an overkill).

markspanbroek commented 9 months ago

Very nice, thank you @SirNickolas!