Object.toString, toHash, opCmp, opEquals
Quirin Schroll
qs.il.paperinik at gmail.com
Thu Jun 6 09:57:29 UTC 2024
On Thursday, 6 June 2024 at 08:00:40 UTC, Ogi wrote:
> On Wednesday, 5 June 2024 at 17:42:20 UTC, Quirin Schroll wrote:
>> except for `toString`
>
> Well, we could make it compatible with @nogc:
> ```D
> void toString(scope void delegate(in char[]) pure nothrow @nogc
> sink) const scope pure nothrow @nogc
> ```
That’s actually a big no. Such a `toString` can’t be used e.g. to
append the characters to an array as that’s not a `@nogc` sink.
You need 16 overloads, all but 1 of them `final`, the non-`final`
one without attributes. Then, derived classes could override the
non-attributed version where the attributed versions (the `final`
ones in `Object`) call the overridable one and do a little
casting so that it’s possible. This sounds great on first glance,
but the issue here is that this approach assumes that the
`toString` implementation is essentially compatible with all
attributes except for the `sink` call. While the default
implementation in `Object` can have this property, overriders may
not be, and if they’re not, there’s no error (or warning).
In cases like `opApply`, that approach works, but only because
one can statically know that the implementation will respect
attributes. For classes, due to overriding, one cannot.
What would be needed is a notion of attribute variables, similar
to how `inout` is a type qualifier variable. Then,
```d
void toString(scope void delegate(in char[]) xpure xnothrow
@xnogc sink) const scope xpure xnothrow @xnogc;
```
makes sense. Overriders would be bound to the same relative
respect to attributes.
The correct choice is a template, but templates cannot be virtual.
More information about the Digitalmars-d
mailing list