Generality creep
Timon Gehr
timon.gehr at gmx.ch
Mon Apr 1 21:23:11 UTC 2019
On 19.03.19 03:52, Andrei Alexandrescu wrote:
>
> Turns out the second clause fails. That takes us to the definition of
> empty in the same module:
>
> @property bool empty(T)(auto ref scope const(T) a)
> if (is(typeof(a.length) : size_t))
> {
> return !a.length;
> }
> ...
Why should length be required to be `const` when almost everything
that's `const` is not even a range?
> 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. Cool. But empty doesn't work with
> TestAliasedString due to an overlooked matter: the "const". A mutable
> TestAliasedString converts to a string, but a const or immutable
> TestAliasedString does NOT convert to a const string! So this fixes that
> matter:
>
> struct TestAliasedString
> {
> string get() @safe @nogc pure nothrow { return _s; }
> const(string) get() @safe @nogc pure nothrow const { return _s; }
> alias get this;
> @disable this(this);
> string _s;
> }
>
Reasoning from first principles, the right fix is actually to allow
non-const 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 problem isn't `alias this`. It's `const`. The following type does
not pass isInputRange either:
struct ApparentlyNotARange{
size_t k=10;
int front(){ return 0; }
void popFront(){ --k; }
@property size_t length(){ return k; }
}
While this does:
struct ApparentlyNotARange{
size_t k=10;
int front(){ return 0; }
void popFront(){ --k; }
@property size_t length()const{ return k; }
}
The reason why Phobos ought to be under the obligation to cater for such
a type is because failure to do so is an artificial limitation. It works
by default, but someone went out of their way to make sure it does not
work if `length` is not annotated `const` (or `@property`). This is
particularly strange because there is no such thing as a const range.
More information about the Digitalmars-d
mailing list