-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Conditional continuation operator for options #9161
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
Conversation
This is usually called "existential operator". I think it's better if you use this name in the docs. Searching for "continuation operator" in Google brings results for "line continuation" |
Aah, good idea. Wasn't really sure what to call this |
injected = nnkDotExpr.newTree( | ||
nnkDotExpr.newTree(opt, newIdentNode("unsafeGet")), firstBarren) | ||
|
||
result = quote do: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will cause performance problems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That it's wrapped in a proc? Any idea how to avoid it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this pattern (https://en.wikipedia.org/wiki/Immediately-invoked_function_expression) in Nim can use block expressions:
var i = 0
let a = block:
if i == 0:
i+2
else:
i*3
echo a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic in the current procedure is not that simple though, this is what would be generated for something that returns a value:
(proc (): auto =
let :tmp130615 = x
if :tmp130615.isSome:
return some(:tmp130615.unsafeGet.slice(3)[0]))()
As you can see it uses auto as the type and relies on Nim to create the default none
value regardless of the type, so it doesn't have an else branch to the if case. I tried wrapping this up in a block statement, but without luck.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
result = quote do: | |
result = quote do: | |
(proc (): auto {.inline.} = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah making it inline is probably a good idea, but if I apply your suggested cange it would be a double proc wouldn't it? Not sure how this new, fancy, GitHub feature works :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh i see, guess I used that new feature wrong myself; maybe just apply the change manually then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## will be ``Option[T]`` where ``T`` is the returned type of ``statements``. | ||
## If nothing is returned from ``statements`` this returns nothing. | ||
## | ||
## .. code-block:: nim |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
runnableExamples + doAssert's instead of echo's ? (otherwise nothing guarantees it stays in sync or keeps compiling)
It doesn't, |
Well it rewrites it to something that should work with the original order: (proc (): auto =
let x = a # In case `a` is a procedure that returns an option
if x.isSome: # Note that this has no else branch, relies on `auto` and the default value of `option` to resolve this
some(x.unsafeGet.b[c])
)() Shouldn't that keep the ordering the same? |
return some(`injected`) | ||
)() | ||
|
||
when isMainModule: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we have optionsutils package which implements all the features proposed in this PR. Closing. |
This adds a Rust-like
?.
operator to Nim which will only evaluate further if the value of the preceding option is a some. In that case it will unwrap the value and pass it on to the right hand side. The entire thing returns an option of the final value, or none if the left hand side is a none, or nothing in case the right hand side doesn't return anything.Depends on PR #9160