On 24.03.2018 05:03, Manu wrote:
On 23 March 2018 at 20:17, Timon Gehr via Digitalmars-d
<digitalmars-d@puremagic.com> wrote:
On 24.03.2018 02:16, Manu wrote:

This is an interesting point, but I don't think it changes the balance
in any way. Thinking of the majority of my anecdotal cases, I don't
think it would be a problem.
Something complex enough for const to be a problem likely doesn't
conform to this pattern.


Why aim for "it often works", when we want "it always works"? Forcing const
upon people who want to pass rvalues by reference is just not good enough.
It is bad language design.

I think you need to re-read the whole thread, and understand what
we're even talking about. ...

That will not be necessary. I wouldn't even have had to read it the first time. Those discussions always go the same way:

M: I wish we could pass rvalue arguments to ref parameters.
J: That would be terrible, as people would then pass rvalues as ref by accident and not see the mutation that the author of the function intended them to see.
M: Only do it for const ref parameters then.
T: No, this has nothing to do with const.

(M can be replaced by a variety of other letters; this is a somewhat common feature request.)

Nobody wants to pass rvalues by mutable-ref... that's completely
pointless, since it's an rvalue that will timeout immediately anyway.
Passing by const-ref is perfectly acceptable.
...

Your temporary might have mutable indirections. Maybe you don't want to be forced to annotate your methods as const, limiting your future options.

I suspect Jonathan's talking about classic D situations with const
like, I might pass by const-ref, but then I can't call a getter that
caches the result.
That's a classic problem with D's const, and that's not on debate
here. I don't think that has any impact on this proposal; people
understand what const means in D, and that's no different here than
anywhere else.
...

Your proposal _changes_ the meaning of const. I.e., "const does all it did previously and now it also allows rvalues to be passed to ref functions". This is bad, as one has little to do with the other, yet now you couple them. Programmers who want to pass rvalues as ref do not necessarily want to use D const on their objects.


Also I think the point about documenting mutation intent is moot, as rvalues
can be receivers for method calls, which will _already_ pass an rvalue by
reference no matter whether it intends to mutate it or not. We can require
some special annotation for this behavior, but I'd be perfectly fine without
it.

I have no idea what this paragraph means... can you elaborate further
what you're talking about?


This works:

struct S{
    int x;
    void inc(){
        this.x++; // note: 'this' is passed by ref
    }
}

void main(){
    S().inc();
}

but this does not:

struct S{
    int x;
}
void inc(ref S self){
    self.x++; // note: 'self' is passed by ref
}

void main(){
    S().inc();
}

I.e. there is a special case where your rewrite is already applied. Note how "inc" cannot even be made const.

What I'm saying is that I don't really buy Jonathan's argument. Basically, you should just pass the correct arguments to functions, as you always need to do. If you cannot use the result of some mutation that you need to use, you will probably notice.


There are only three sensible ways to fix the problem:

1. Just allow rvalue arguments to bind to ref parameters. (My preferred solution, though it will make the overloading rules slightly more complicated.)

2. Add some _new_ annotation for ref parameters that signifies that you want the same treatment for them that the implicit 'this' reference gets. (A close second.)

3. Continue to require code bloat (auto ref) or manual boilerplate (overloads). (I'm not very fond of this option, but it does not require a language change.)

Reply via email to