Motive behind !empty() with front() instead of Optional front()
Q. Schroll
qs.il.paperinik at gmail.com
Sat Apr 10 02:14:58 UTC 2021
On Friday, 9 April 2021 at 21:17:03 UTC, Paul Backus wrote:
> On Friday, 9 April 2021 at 20:40:54 UTC, Q. Schroll wrote:
>>
>> As Andrei said, in C++, apart from the `decltype` exception
>> (which is justified), references behave as aliases. In D, it's
>> the same, apart from `__trais(isRef)` which is also justified.
>> What else do you expect from a reference object? Maybe I'm
>> biased, but I don't see how other solutions than C++'s would
>> be better.
>
> Hypothetically, if `ref` were a type qualifier, I'd expect it
> to behave the same way as D's other type qualifiers. We don't
> strip `const` or `shared` from types during template
> instantiation (the special case of `const(T[])` → `const(T)[]`
> notwithstanding), so my baseline expectation is that we
> wouldn't strip `ref` either.
>
> Maybe there's an argument to be made that this is a bad idea,
> and that you should always be able to replace an lvalue with a
> reference without any effect on the program's behavior. But I
> don't think you can take it as given that that's *obviously*
> the correct way to do references, just because that's what C++
> does.
The "special case of `const`" is exactly the point: If you have a
`const(T[]) ts` object and you do
```D
auto ts2 = ts;
```
then, `typeof(ts2)` is `const(T)[]`. The whole point of making a
copy is that it (or at least the first layer) becomes independent
and mutable. I think references should behave the same: Assigning
a `ref(T)` to an `auto` variable should create a copy that (or at
least the first layer) is independent of the source. Creating
another reference is near-useless.
When it comes to parameter passing, binding by copy is expected
to be the default and binding by reference a specialty. One
reason being that binding by copy is more flexible, e.g. it
allows (implicit) conversions.
I don't think it's obviously the right way because C++ does it
that way, but it's a hint. I came to the conclusion myself;
thinking of various alternatives, I could see obvious problems.
C++'s references have (obvious?) problems, so it's not like it's
perfect. IMO, `ref` as a storage class is the Right Thing. D
falls short in some places:
* Allowing `ref` for local variables would be valuable at times.
There's no actual gain in not allowing them. Some stuff like
postfix operators even lower to `ref` local variables.
* One cannot directly express `ref` returning delegate or
function pointer types on many occasions, e.g. neither `is(DG ==
ref int delegate())` nor `is(DG == int delegate() ref)` compile.
Also, one cannot directly specify `ref` returning delegate or
function pointer types in parameter lists. In both cases, an
alias has to be defined.
If `ref` were a type constructor, these would be non-issues for
sure. But we're nowhere near *requiring* it to be one to solve
these.
More information about the Digitalmars-d
mailing list