Optional and orElse: design feedback/critique?

aliak something at something.com
Sun Jul 28 03:16:41 UTC 2019


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.




More information about the Digitalmars-d mailing list