July 28, 2019 Re: Optional and orElse: design feedback/critique? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Sunday, 28 July 2019 at 00:05:19 UTC, Paul Backus wrote: > > As suggested elsewhere in this thread, treating both null references and null pointers as empty would also be a reasonable decision. The inconsistency is the real issue here. Aye, I agree. > >> The thing is I want it to "just work" based on the call site. So if a user does a.orElse(literal) on a container type, it's [...] > or me, and instead it gives me a third thing that I didn't ask for (e.g., `a.front`), I am going to be very confused. Ha! Touche. I am convinced. > > For Optional, there's a one-to-one correspondence between the container and the value inside it, so eliding the distinction [...] >g when they get in your way. After all, when someone > iterates over a range of UTF-8 code units, it's "pretty obvious" that what they want is code points, right? > >> So make coalescing separate from orElse-ing is basically the gist of this right? > > As I understand it, coalescing means flattening or unwrapping multiple layers of Optional at once. So, yes, orElse definitely shouldn't be doing that. But I'm guessing that's not what you meant to say. I was thinking in terms of the null coalescing operator found in some languages. So a ?? b will give you a if it's not null and b otherwise, which is what orElse was doing if b was a range/optional. > >> Sorry, what was the `some(val1.orElse(val2))`? Did you mean that instead of range1.orElse(range2) or range1.orElse(elementOfRange)? > > Sorry, that was an incorrect example. What I was trying to say was, I don't think Optional.orElse should have two different return types depending on its arguments. If you want to have a version that unwraps its first argument and a version that doesn't, it would be better to give them different names, so it's always obvious which is being used. For example: > > Optional!int a = no!int; > Optional!int b = some(123); > > int x = a.valueOrElse(123); // unwraps > Optional!int y = a.orElse(b); // doesn't unwrap > > This is how they do it in Rust: the non-unwrapping version is called `or`, and the unwrapping version is called `unwrap_or`. Thanks for the feedback. It looks like I'll be going with frontOrElse, orElse, and making the null semantics consistent. |
Copyright © 1999-2021 by the D Language Foundation