Why can't we define re-assignable const reference variable?

Steven Schveighoffer schveiguy at yahoo.com
Tue Feb 19 13:34:39 PST 2008


"Walter Bright" wrote
> Sergey Gromov wrote:
>> I'm talking from the standpoint of generalization which you so much care 
>> about.  When I generalize, I don't care how things are implemented.  It's 
>> behaviour that matters.  If I create an algorithm that uses references to 
>> invariant data, then it will work with anything that /behaves/ like such 
>> references.  Even if they are actually ints passed by value.
>
> That's a good point, and a good reason why:
>
> invariant(C)[] c;
> invariant(int)[] i;
>
> should both have immutable array contents, i.e. if the contents of a 
> reference is invariant then the reference itself should be invariant.
>
> The concept of having a mutable reference to immutable data is 
> fundamentally flawed because it breaks the concept of what a reference is. 
> A reference is not separable from what it refers to. If they were 
> separable, they would be syntactically and semantically the same thing as 
> pointers, and there would be no point whatsoever to even having a 
> reference type.

So please explain this:

import std.stdio;

class C
{
    this(int n) {x = n;}
    int x;
}

void assignit(ref int src, ref int value)
{
       src = value;
}

void assignit(C src, C value)
{
       src = value;
}


void main()
{
    int n = 1;
    int m = 2;

    C c = new C(1);
    C d = new C(2);

    assignit(n, m);
    assignit(c, d);

    writefln("%s %s %s %s", n, m, c.x, d.x);
}

// outputs 2 2 1 2

In both cases, the assignit function is taking reference types as arguments. 
C is a reference type because it is a class.  ref int is a reference type 
because the compiler magically creates a reference.  Both do the same thing, 
but yet the class version doesn't result in the value changing, because we 
are rebinding the reference, not copying the class itself.  This is why your 
argument fails.  There are some cases in D where references are treated as 
non-rebindable pointers to data, where acting on the reference is equivalent 
to acting on the pointed at data, and then there are classes, where you can 
rebind the reference in some cases, but in other cases you are acting on the 
data pointed to.

I'm not saying that references should always be non-rebindable (I like the 
way classes work) or always be rebindable, I'm just saying that your 
argument against allowing references to be acted upon separate from the data 
is against the way the language/compiler currently is implemented.

You can make the case that class references are not the same as 
non-rebindable references, and also that they are not like pointers.  I 
would say that they are exactly like pointers except you cannot dereference 
them or perform general arithmetic on them.  This puts them in a category on 
their own, which I think is fair game to say that it is reasonable that we 
can ask for that category to be modified without affecting the consistency 
of the other categories.

The specific modification being that you can const-ify the data pointed to 
by a class reference without modifying the reference constness itself.

-Steve 





More information about the Digitalmars-d mailing list