At status, we've successfully been using Result for the past two years, and it has helped improve the quality of our code-base tremendously - we write a lot of libraries where the additional explicitness in the API helps users of the libraries understand how the library work and the explicit control flow at every call site is the difference between night and day in terms of how well error handling ends up working, from a very pragmatic point of view - this is important specially in our long-running applications. It's fair to say that the concept is now fairly well battle-tested in the wild.
One outcome of having worked with it is a new PR that just landed - if you've been using Result, do take a look or provide your feedback in this thread.
Of the new features, one that's particularily interesting Result[T, void] can now almost be used as a drop-in replacement for Option[T] in the form of a new alias: Opt[T] - there's a lot shared characteristics between the two, but using Result across the board makes interop smooth and easy, because all code gets the same "look and feel".
Going forwards from here, we might add a few other bells and whistles if they prove useful in actual use - let me know if there's anything in particular you'd like to see, preferably with code examples!
What are the advantages over Option[T]?
How does this fit into the monadic pattern?
I'm guessing this: https://github.com/arnetheduck/nim-result
I've been rolling my own result types but i may start using this now that i know about it. Exceptions are probably my least favorite thing in nim, though i know there are tradeoffs here.
I'm guessing this
Indeed, that's the one ;)
but the general idea is that one should follow the error pattern used the library/language
Result has excellent exception support allowing you to switch freely between the two paradigms or write libraries that pass this choice convenient for the user of the library - exceptions are deeply problematic however, for many use cases - in those cases, a different tool is needed - consider C++ for example: exceptions exist, but many choose not to use them because of the costs involved (cognitive, quality and performance costs above all).
Regarding following the herd, consider something as trivial as int - Nim favors int which panics on overflows and underflows, causing your application to crash - that's clearly not the optimal choice for every application out there - in fact, in many cases, saturating or wrapping makes a lot more sense / is the better way to deal with the limited range of int (not to mention the platform-specific behaviors it introduces). Sure, you can work around the quirks of int, but at some point that's stops being the rational way forward.
And I don't even like exceptions, it's just I dislike the alternative designs (that includes Result btw) much moreso.
The application does "panic" though
panic = crash? I mean...
not if you manage to wrap your requests/whatever in a try..except block.
over/underflow = Defect = doesn't work with try/except
IMHO the way Nim does it does work reasonably well
what works reasonably well really depends more on the problem than the language and the team - ie across the board for the data we've looked at, Nim code that uses exceptions has more issues with resource leaks and unhandled edge conditions than other code we look at - this is quite consistent across the std lib, libraries and our own experience (multiple teams) - sometimes that's not a problem: if restarting the application is cheap (like a script or a one-off), it doesn't matter at all.
For int specifically, again, it really depends on the use case: if you work with numbers in the "human" range - counts that a normal person can comfortably imagine, int is great - but you obviously don't want to use an int for a fast hash function - there you want wrapping behavior - same if you're writing a bigint library or working with elliptic curve cryptography or zero knowledge - int is quite terrible in those cases.
Result falls neatly into the same category: it's really really good for certain use cases, even if some programmers never have run across them.
@moigagoo
Result (sometimes also called Maybe) is a type system convention that behaves a bit like exceptions in that there's a correct path and an error path, except you're usually forced to handle it at compile time at the call site instead of the exception bubbling up if it's unhandled.
It avoids some runtime issues where error values may have been encoded as negative values, null, etc., and the programmer forgot to handle those cases.