Optional and orElse: design feedback/critique?

Alexandru Ermicioi alexandru.ermicioi at gmail.com
Sat Jul 27 17:35:52 UTC 2019

On Saturday, 27 July 2019 at 16:26:26 UTC, aliak wrote:
> On Saturday, 27 July 2019 at 14:46:55 UTC, Alexandru Ermicioi 
> wrote:
>> On Saturday, 27 July 2019 at 13:17:32 UTC, aliak wrote:
>>> Hi,
>>> Can I ask for feedback on what people expect an 
>>> optional/maybe type to have, and how to behave. There have 
>>> been a number of discussions on the forums about it so far, 
>>> and attempted PRs in phobos.
>> Would be nice to have functionality similar to Optional from 
>> java 8+, such as orElseThrow, orElseGet, ifPresent etc. Also
> A lot of the java stuff is covered with std.algorithm and orElse
> auto a = some(3);
> auto gotValue = a.orElse(7); // orElseGet
> a.each!(a => writeln(a)); // ifPresent

Haven't thought this way. This is something I like in D, 
everytime you discover something hidden in it.

> orElseThrow on the other hand would have to be added 
> separately. I use that quite often as well but I can't work it 
> in to the provided orElse because "throw blah" is not an 
> expression. I have another experimental thing where that's 
> available though -> 
> https://aliak00.github.io/ddash/ddash/utils/orelse/orElseThrow.html (but that library is not the most stable for now)
> One other way would be to add an expression throw:
> off top of me head:
> auto throw_(T : Throwable)(lazy T e) { throw e(); }
> Then this would work:
> a.orElse(throw_(new Exception("")));

Hmm trying to use orElse for throwing I'd say is kinda over 
engineering. A simple orElseThrow (throw_) on optional itself 
would be best to have, plus autocompletion would work and it is 
easier to discover by newbies to lib itself.

>> would be nice if it worked perfectly with immutable/const 
>> data, and when Optional itself is immutable/const. Another nice
> You can currently wrap cost/immutable data. I try to test to 
> ensure things work with qualified optionals [0], but it's 
> tricky with the const system in D, and with how inout behaves 
> with wrapper objects [1, 2]. The other problem here is that 
> const ranges are not ranges. So maybe a decay function on an 
> optional type?
> const a = some(3);
> a.decay.map...
> [0]: 
> https://github.com/aliak00/optional/blob/de223a7d63d346386b0d02d119cf4bdd79366299/tests/optional.d#L11
> [1]: https://issues.dlang.org/show_bug.cgi?id=19126
> [2]: https://issues.dlang.org/show_bug.cgi?id=19125
>> feature would be conversion from immutable to const optional, 
>> and from immutable/const optional to mutable Optional with 
>> const payload through probably copy constructor and opCast 
>> methods.
> Hmm. Yes. The latter can probably be handled with the 
> "decay-like" function. Isn't the former handled by D anyway? 
> immutable is implicitly convertible to const?
> immutable a = some(3);
> const Optional!int b = a;

Yep immutable and mutable optional is implicitly convertible to 
const, still we'd need copy constructor for const case accepting 
inout. For later opCast should be perfect match, and we'd also 
need copy constructors matching opCast.

Also it is interesting if it is possible to make whole optional 
@safe. Emsi containers for example templatized all functions in 
order to have attribute autodeduction, which is kinda think is 
overkill in my opinion plus it doesn't allow to have nice 
interfaces similar to java collections. Maybe some of optional 
methods could be marked as safe, such as front or empty provided 
they avoid any invocation of overloaded operators in payload 
itself, as they could be @system.


More information about the Digitalmars-d mailing list