On Fri, 09 Nov 2012 16:26:21 -0000, martin <[email protected]> wrote:
Let me summarize my (final, I guess) proposal. I think it makes sense to
compare it to C++ in order to anticipate and hopefully invalidate
(mainly Andrei's) objections.
parameter type | lvalue | rvalue
| C++ D | C++ D
------------------------|-------------|------------
T | copy copy | copy move
T& / ref T | ref ref | n/a n/a
out T (D only) | ref | n/a
T&& (C++ only) | n/a | move
auto ref T (D only) (*) | ref | ref
------------------------|-------------|------------
const T | copy copy | copy move
const T& / const ref T | ref ref | ref ref (*)
const T&& (C++ only) | n/a | move
(*): proposed additions
For lvalues in both C++ and D, there are 2 options: either copy the
argument (pass-by-value) or pass it by ref. There's no real difference
between both languages except for D's additional 'out' keyword and, with
the proposed 'auto ref' syntax, an (imo negligible) ambiguity between
'ref T' and 'auto ref T' in D.
Rvalues are a different topic though. There are 3 possibilites in
general: copy, move and pass by ref. Copying rvalue arguments does not
make sense - the argument won't be used by the caller after the
invokation, so a copy is redundant and hurts performance. D corrects
this design flaw of C++ (which had to introduce rvalue refs to add move
semantics on top of the default copy semantics) and therefore only
supports moving instead. C++ additionally supports pass-by-ref of
rvalues to const refs, but not to mutable refs. I propose to allow
pass-by-ref to both const (identical syntax as C++, it's perfectly safe
and logical) and mutable refs (new syntax with 'auto ref' to emphasize
that the parameter may be an rvalue reference, with related consequences
such as potentially missing side effects).
Regarding the required overloading priorities for the proposed additions
to work properly, I propose:
1) lvalues: prefer pass-by-ref
so: ref/out T -> auto ref T (*) -> const ref T -> (const) T
- const lvalues: const ref T -> (const) T
- mutable lvalues: ref/out T -> auto ref T (*) -> const ref T ->
(const) T
2) rvalues: prefer pass-by-value (moving: argument allocated directly on
callee's stack (parameter) vs. pointer/reference indirection implied
by
pass-by-ref)
so: (const) T -> auto ref T (*) -> const ref T (*)
Finally, regarding templates, I'm in favor of dropping the current 'auto
ref' semantics and propose to simply adopt the proposed semantics for
consistency and simplicity and to avoid excessive code bloating. That
shouldn't break existing code I hope (unless parameters have been
denoted with 'const auto ref T', which would need to be changed to
'const ref T').
Now please go ahead and shoot. :)
Nice detailed proposal. I would suggest starting a new thread with it, to
catch anyone who dozed off in this thread :p
R
--
Using Opera's revolutionary email client: http://www.opera.com/mail/