Generality creep

Kagamin spam at here.lot
Tue Mar 19 09:01:00 UTC 2019


On Tuesday, 19 March 2019 at 02:52:34 UTC, Andrei Alexandrescu 
wrote:
> @property bool empty(T)(auto ref scope const(T) a)
> if (is(typeof(a.length) : size_t))
> {
>     return !a.length;
> }
>
> The intent is fairly clear - if a range defines empty as a 
> size_t (somewhat oddly relaxed to "convertible to size_t"), 
> then empty can be nicely defined in terms of length.

If it was intended for arrays only, then
@property bool empty(T)(scope const T[] a)
{
     return !a.length;
}

But if not, what is the reason to define length, but not empty? 
Anyway, the type may need to be mutable, e.g. it might want to 
allocate and store the array, so
@property bool empty(T)(auto ref scope T a)
if (is(typeof(a.length) : size_t))
{
     return !a.length;
}

> That makes empty() work, but also raises a nagging question: 
> what was the relationship of TestAliasedString to string before 
> this change? Surely that wasn't subtyping. (My response would 
> be: "Odd.") And why was Phobos under the obligation to cater 
> for such a type and its tenuous relationship to a range?

The design rationale is not documented :) so we can only guess.
My guess is that it was done for some string container 
(appender?) that returns rvalue string, so the change to ref 
return would be incorrect.

> But wait, there's more. Things still don't work because of 
> popFront. Looking at its definition:
>
> void popFront(C)(scope ref inout(C)[] str) @trusted pure nothrow
> if (isNarrowString!(C[]))
> { ... }
>
> So, reasonably this function takes the range by reference so it 
> can modify its internals. HOWEVER! The implementation of 
> TestAliasedString.get() returns an rvalue, i.e. it's the 
> equivalent of a conversion involving a temporary. Surely that's 
> not to match, whether in the current language or the one after 
> the rvalue DIP.

That's conflation of collections and ranges. A collection would 
be a range factory.

> What's the moral of the story here? Generality is good, but it 
> seems in several places in phobos (of which this is just one 
> example), a combination of vague specification and aiming for a 
> nice ideal of "work with anything remotely reasonable" has 
> backfired into a morass of inconsistently defined and supported 
> corner cases.
>
> For this case in particular - I don't think we should support 
> all types that support some half-hearted form of subtyping, at 
> the cost of reducing generality and deprecating working code.

Isn't generality one of phobos acceptance criteria?


More information about the Digitalmars-d mailing list