Motive behind !empty() with front() instead of Optional front()

Steven Schveighoffer schveiguy at gmail.com
Fri Mar 26 15:53:39 UTC 2021


On 3/24/21 3:23 PM, Per Nordlöw wrote:
> What's the motive behinds D's range design choice of needing
> 
>      if (!empty)
>      {
>          // use front or back
>      }
> 
> instead of having front returning an optional/maybe type with enforced 
> pattern matching?
> 
> Lack of builtin Optional type?
> 
> Choosing the Optional path would have avoided the need for putting error 
> diagnostics such as
> 
> https://github.com/dlang/phobos/commit/9bd2f2ba8ff1124a044560c4e6912a13cb5ac694 
> 
> 
> in the standard library of such an alternative solution.

I would say separation of concerns. Consider:

int someExpensiveCalc(int);

auto r = someArr.map!someExpensiveCalc;

r.empty is simply a forward to someArr.empty. However, r.front calls 
someExpensiveCalc (if not empty).

So code that looks specifically at emptiness might not want to trigger 
the expensive call unnecessarily. e.g. canFind.

Since empty is a distinct abstraction, it's the simplest building block. 
You can actually MAKE a "range-like" thing that uses empty to produce 
what you want. It's problematic the other way around.

That being said, there is definitely a case for straight-input-ranges to 
have a different API (maybe one without empty), since iterating a 
non-forward range can possibly destroy it, and if you change the API to 
simply an Optional!T next(), then you don't need to cache the element 
(currently I think the biggest wart in the range system).

But such a thing would have to possibly be supported in the language 
(ranges are a language feature in that they hook to foreach, I would 
expect the same for such input ranges).

Regarding the question about the github commit, that's an entirely 
different thing. Notice that it's an assert, which means it can be 
removed in correctly-written programs. If you return an Optional, 
emptiness MUST be checked on every access to an element, even when you 
know (or have proven) it's not empty.

I would support a new kind of range that uses `Optional!T next()` as its 
API. I would not support `Optional!T front(); void popFront()`.

-Steve


More information about the Digitalmars-d mailing list