codex-storage / questionable

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

bug: binding to optional callbacks, with `.catch` fails to compile #57

Closed emizzle closed 6 months ago

emizzle commented 6 months ago

When binding to optional callbacks, with .catch, it seems that the compiler can't figure out the type of callback? Tried this on nim v1.6.18.

import std/json
import std/tables
import pkg/questionable
import pkg/questionable/results

{.push raises:[].}

type
  SubscriptionCallback = proc(id, arguments: JsonNode) {.gcsafe, raises:[].}

proc getCallback(): ?SubscriptionCallback {.raises: [KeyError].} =
  raise newException(KeyError, "blah")

if cb =? getCallback().catch:
  cb()

Does not compile:

Error: attempting to call routine: 'cb'
  found 'cb' [let declared in /Users/egonat/repos/status-im/nim-ethers/vendor/.nimble/pkgs/questionable-0.10.13/questionable/binding.nim(84, 5)]
markspanbroek commented 6 months ago

getCallback() returns an Option, and .catch wraps that in a Result, so the expression getCallback().catch is of type ?!(?SubscriptionCallback) The =? operator only unwraps the outer Result, but the inner Option remains. That's why you get a compiler error.

When you unwrap the option then it does compile:

if maybeCallback =? getCallback().catch and callback =? maybeCallback:
  callback(JsonNode(), JsonNode())
emizzle commented 6 months ago

Makes sense, thanks Mark!