-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add allSome macro to options which safely unwraps options #9162
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
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.
Either
name is good, Reading some of the examples of allSome
it kind of read weirdly, maybe allMatch
instead?
Also those code-blocks should be runnableExamples
## let x = allSome(["abc".find('b'), "def".find('f')]): | ||
## some [firstPos, secondPos]: firstPos + secondPos | ||
## none: -1 | ||
## echo x # Prints out "3" (1 + 2) |
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.
Those should probably be runnableExamples
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.
Last I tried this it didn't work as runnableExamples. That issue might've been fixed by now though so I'll check it out.
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.
Appears to work, although I do have to add in import options
and an implementation of the find
procedure that returns an option.
none(T) | ||
else: | ||
self | ||
template either*(self, otherwise: untyped): untyped = |
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.
I like the name
else: | ||
self | ||
|
||
macro allSome*(options: untyped, body: untyped): untyped = |
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.
Maybe allMatch? reading some of the examples is a bit awkward
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, this was Araq's latest suggestion. Problem is that it doesn't really do "matching" in the grand sense of the word, it just checks the has-ity of the options..
This is so neat, thanks for pushing it forward @PMunch :) |
Thanks @superfunc, do you have any naming suggestions? |
Naming is hard haha, I can't think of a better one. |
I am not entirely sure if a special macro is needed for this: a general enough pattern matching library should be able to do it. E.g. in gara it should be almost possible(needs a tuple support fix) to define an unpacker allSome and do match (e, f, g): # options
of allSome(@e1, @f1, @g1):
echo e1
else:
echo 0 On the other hand if we need allSome in the stdlib, there is no other way but a special-case macro I guess |
Problem is there is no pattern matching library in the stdlib and now that nilseqs and nilstrings are removed from the language and options take over their functionality I feel like we need a better way to handle options. |
Can't we put this in a Nimble package for now and see what the adoption looks like? I wasn't around for the discussion relating to splitting |
There already is a similar Nimble package which I've based this on since I felt like it would be a natural part of the stdlib. The splitting of options was a request from Araq, I've got no issue reverting it if he's changed his mind. You've said yourself that options are clunky and impractical to use, this fixes the problem in a safe and elegant way. With options now presumably being used more, or at least being made more visible to people as it's mentioned each time nilstring and nilseqs are mentioned, I felt like there was a need to make them more practical. I'm using the original package in a project I'm working with right now and it's a lot better than using the current Nim stdlib way. |
@PMunch I agree, probably there isn't gonna be pattern matching in the stdlib soon. I am just afraid we might have one day 3 slightly different dsl-s for different unwrapping/matching scenarios. |
I haven't, I still like the split. |
I agree, the split is nice. |
First of all I would like to say, I like the split, but that is already part of the other PR. This is not about that. I don't like it, because it is too complicated. An option is nothing more that a value that might be there or that might be not there. You create an entire language about option expressions. This language probably has it's own quirks and is hard to maintain. I am sorry for your work that you put into this, but as the maintainer I have to reject this. |
This is based on the safe pattern for unwrapping options found in https://github.com/superfunc/maybe but is extended to allow not only a single option, but multiple. It's also made safe from side-effects.
allSome
accepts a list of options (or a single option), and two blocks. One in which all the options are unpacked, the other in which one or more of the options doesn't have a value. This ensures that no safe unpacking of options occurs, and allows the user to check multiple options in a simple way.Depends on PR #9160