On Saturday, 26 January 2019 at 06:15:22 UTC, Walter Bright wrote:
On 1/25/2019 7:44 PM, Manu wrote:
I never said anything about 'rvalue references',
The DIP mentions them several times in the "forum threads"
section. I see you want to distinguish the DIP from that; I
recommend a section clearing that up.
However, my points about the serious problems with @disable
syntax remain.
A section comparing with the C++ solution is necessary as well,
more than the one sentence dismissal. For example, how C++
deals with the:
void foo(const int x);
void foo(const int& x);
situation needs to be understood and compared. Failing to
understand it can lead to serious oversights. For example, C++
doesn't require an @disable syntax to make it work.
[...]
Should `s` be promoted to an int temporary, then pass the
temporary by
reference? I can find no guidance in the DIP. What if `s` is
a uint (i.e. the
implicit conversion is a type paint and involves no
temporary)?
As per the DIP; yes, that is the point.
The text you seek is written: "[...]. The user should not
experience
edge cases, or differences in functionality when calling
fun(int x) vs
fun(ref int x)."
I don't see how that addresses implicit type conversion at all.
Anything that could be implicitly converted to use foo(int) can
be implicitly converted to pass a ref to the temporary that was
implicitly converted to int into foo(ref int). No rules change in
this regard. If you don't see how this address type conversion
perhaps a code sample might help? The one that was given with
short:
void foo(ref int);
void bar(int);
bar( short(10) ); // is ok
foo( short(10) ); // expected to be ok short->int ; ref to temp
passed to foo
Just as bar(int) can be passed a short(10), foo(ref int) can be
passed a reference to the temporary that was created as well.
Don't accept naked ref unless you want these semantics. There
is a
suite of tools offered to use where this behaviour is
undesirable.
Naked `ref` doesn't do anything particularly interesting in the
language today that's not *identical* semantically to using a
pointer
and adding a single '&' character at the callsite.
It's not good enough. The DIP needs to specifically address
what happens with implicit conversions. The reader should not
be left wondering about what is implied. I often read a spec
and think yeah, yeah, of course it must be that way. But it is
spelled out in the spec, and reading it gives me confidence
that I'm understanding the semantics, and it gives me
confidence that whoever wrote the spec understood it.
(Of course, writing out the implications sometimes causes the
writer to realize he didn't actually understand it at all.)
Furthermore, D has these match levels:
1. exact
2. const
3. conversion
4. no match
If there are two or more matches at the same level, the
decision is made based on partial ordering. How does adding the
new ref/value overloading fit into that?
The DIP goes over this, though not in a lot of detail. All the
same rules apply as with the current implementation. Where there
would be a compiler error trying to pass an rvalue would instead
forward the value.
Effectively what is being implemented is the following (for type
matching only):
void foo( ref int );
void foo( int value ) { foo( value ); }
Anything that would have been passed to foo(int) is passed to
foo(ref int) as a reference to a temporary instead. No rules are
changed in this regard for matching, all the same rules apply (as
stated in the DIP). It's pretty clear, unless you can give a
specific problem faced where this doesn't hold? D is pretty
strict to ensure rvalues aren't passed to ref's and that's what
makes this relatively simple to implement without changing
matching rules.