First Draft: opUnwrapIfTrue
Dejan Lekic
dejan.lekic at gmail.com
Mon Sep 21 18:54:44 UTC 2026
On Thursday, 26 February 2026 at 13:53:41 UTC, Richard (Rikki)
Andrew Cattermole wrote:
> The DIP:
> https://gist.github.com/rikkimax/21242118e3bc1bf5f28024c2cdc33557
>
> A new operator overload to allow if statements to automatically
> unwrap result types and ensure that the check is called prior
> to, similar to foreach statements support of ranges.
>
> This solves a prolific issue that I have had to deal with
> result types and has been exhibited by ``Nullable`` in PhobosV2.
>
> Full example:
>
> ```d
> import core.attribute : mustuse;
>
> @mustuse
> struct Result(Type) {
> private {
> Type value;
> bool haveValue;
> }
>
> this(Type value) {
> this.value = value;
> this.haveValue = true;
> }
>
> bool opCast(T:bool)() => haveValue;
>
> Type opUnwrapIfTrue() {
> assert(haveValue);
> return value;
> }
> }
>
> Result!int result = Result!int(99);
>
> if (int value = result) {
> // got a value!
> assert(value == 99);
> } else {
> // oh noes an error or default init state
> }
> ```
I know I am late in this discussion - almost always want error
why use `if` for something that is clearly for error handling.
I would rather have something like:
```
Result!int result = Result!int(99) or {
/* error handling here where `error` just like `this` refers
too the error object */
}
```
I do understand that you guys want to use existing language
primitives everywhere but if I need to use `if` then I would
simply go with the usual if (result.ok) {} else { /* use
result.error() to get error object out of Result!(Error,
ResultValue) */ } or match. Here is an example how it is done in
ddn.result module:
```d
import ddn.result : Result, Success;
struct ParseError { string msg; size_t offset; }
struct Config { int value; }
struct UpdateError { enum Reason { NOT_FOUND, LOCKED } Reason
reason; }
alias ParseResult = Result!(ParseError, Config);
alias UpdateResult = Result!UpdateError;
ParseResult parseConfig(scope const(char)[] text) {
if (text.empty)
return ParseResult(ParseError("empty input", 0));
return ParseResult(Config(1));
}
// Caller-side handling:
auto result = parseConfig("");
if (result.ok()) {
auto config = result.value();
} else {
auto failure = result.error();
}
```
( `result.match()` works too ofc )
Full implementation is here:
https://codeberg.org/ddn/ddn/src/branch/main/src/ddn/result.d
I am glad someone is working on this - it was about the time. But
let's please do it right... My module above is far from best, but
if I had a better one I would have used it. That is what I hope
here. :)
More information about the dip.development
mailing list