Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

result: add result assignment extenstion point for ? #134

Closed
wants to merge 1 commit into from

Conversation

arnetheduck
Copy link
Member

When ? exits early, it does so using variations return v - however,
in frameworks such as chronos, we need to change return v to
future.complete(v) - this feature allows chronos to inject a template
that performs this assignment instead of using the "ordinary" flow.

Risk:

assignResult might already be taken as a name, and multiple frameworks
might compete for the functionality.

Potential alternative:

Instead of assignResult, this construct could be called
returnResult, and it would be responsible for breaking the control
flow (performing the return in addition to assigning the result).

Other interactions:

#34 proposes a general-purpose
conversion framework - this could be used to automatically convert the
error based on existing conversions - the use case is that oftentimes,
one error needs to be converted to another in a call chain and injecting
a converter simplifies this flow - this might however create an
problematic interaction with an assignResult template in the future.

arnetheduck added a commit to status-im/nim-chronos that referenced this pull request Jul 22, 2022
This PR uses the facilities provided in
status-im/nim-stew#134 to support `?` in `async`
proc's.
stew/results.nim Outdated
else:
when E is void:
return err(typeof(result))
when declared(assignResult):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this declared check would actually work for the Chronos use-case. Have you tested it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, there's a test in status-im/nim-chronos#297 - not sure about more complex cases, anything in particular you're worried about?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, OK, I didn't realize the Chronos PR was tested precisely with this version of Result (there was the possibility that assignResult existed a globally defined template that is overloaded in Chronos).

It would be good to test additional use cases such as generic async procs or async closures defined in generic functions as these trigger substantially different symbol lookup paths in the compiler (which may trip the declared check here).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a generic test which seems to work for now - needed an extra mixin inside assignResult to not complain about the result symbol

stew/results.nim Outdated
@@ -953,25 +953,52 @@ template isNone*(o: Opt): bool =
# Syntactic convenience

template `?`*[T, E](self: Result[T, E]): auto =
mixin assignResult
Copy link
Contributor

@zah zah Apr 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a very low-level integration mechanism between advanced Nim libraries, I suggest relying on the Nim `backticks` feature and use an identifier that's extremely unlike to appear in user code (e.g. `#assignResult`). It's also worth re-reading the discussion we had in the Chronos tracker:

status-im/nim-chronos#297 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#assignResult doesn't compile - assignResult? is fine however, switched

arnetheduck added a commit to status-im/nim-chronos that referenced this pull request May 11, 2023
This PR uses the facilities provided in
status-im/nim-stew#134 to support `?` in `async`
proc's.
@arnetheduck arnetheduck marked this pull request as draft May 12, 2023 06:51
@arnetheduck
Copy link
Member Author

marking draft for now - failing in 2.0

arnetheduck added a commit to status-im/nim-chronos that referenced this pull request Jun 4, 2023
This PR uses the facilities provided in
status-im/nim-stew#134 to support `?` in `async`
proc's.
arnetheduck added a commit to status-im/nim-chronos that referenced this pull request Jun 4, 2023
This PR uses the facilities provided in
status-im/nim-stew#134 to support `?` in `async`
proc's.
arnetheduck added a commit to status-im/nim-chronos that referenced this pull request Jun 5, 2023
This PR uses the facilities provided in
status-im/nim-stew#134 to support `?` in `async`
proc's.
@arnetheduck arnetheduck marked this pull request as ready for review June 6, 2023 14:29
arnetheduck added a commit to status-im/nim-chronos that referenced this pull request Jun 6, 2023
This PR uses the facilities provided in
status-im/nim-stew#134 to support `?` in `async`
proc's.
arnetheduck added a commit to status-im/nim-chronos that referenced this pull request Jun 8, 2023
This PR uses the facilities provided in
status-im/nim-stew#134 to support `?` in `async`
proc's.
When `?` exits early, it does so using variations `return v` - however,
in frameworks such as `chronos`, we need to change `return v` to
`future.complete(v)` - this feature allows chronos to inject a template
that performs this assignment instead of using the "ordinary" flow.

Risk:

`assignResult` might already be taken as a name, and multiple frameworks
might compete for the functionality.

Potential alternative:

Instead of `assignResult`, this construct could be called
`returnResult`, and it would be responsible for breaking the control
flow (performing the `return` in addition to assigning the result).

Other interactions:

#34 proposes a general-purpose
conversion framework - this could be used to automatically convert the
error based on existing conversions - the use case is that oftentimes,
one error needs to be converted to another in a call chain and injecting
a converter simplifies this flow - this might however create an
problematic interaction with an `assignResult` template in the future.
arnetheduck added a commit to arnetheduck/nim-results that referenced this pull request Oct 16, 2023
as an alternative to status-im/nim-stew#134,
this PR provides an accidental workaround to the underlying issue, which
is that macros are generally unable to rewrite `template` contents since
the macro rewriting happens before template expansion.

splitting up `result` assignment and `return` allows binding to the
injected `result` and `return` without argument ends up being
"implicitly" compatible with the way `async` code is turned into a
closure iterator.
arnetheduck added a commit to arnetheduck/nim-results that referenced this pull request Dec 21, 2023
as an alternative to status-im/nim-stew#134,
this PR provides an accidental workaround to the underlying issue, which
is that macros are generally unable to rewrite `template` contents since
the macro rewriting happens before template expansion.

splitting up `result` assignment and `return` allows binding to the
injected `result` and `return` without argument ends up being
"implicitly" compatible with the way `async` code is turned into a
closure iterator.
@arnetheduck
Copy link
Member Author

obsoleted by arnetheduck/nim-results#37

@arnetheduck arnetheduck deleted the assign-result branch December 21, 2023 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants