www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - References to const

reply Jonathan M Davis <jmdavisProg gmail.com> writes:
Okay, I'm wondering if there is any way in D to have a reference to const.  As
far as I can tell, if you use const on a reference, you get a constant
reference to constant data.

const A a1;
const A a2 = new A();
A otherA = new A();
const A a3 = otherA;

So, a1 points permanently to null.  You can't change what it points to (and of
course you can't change null).  a2 points to an A which was constructed on
assignment.  a2 can't be made to point to anything else and you can't change
the value that it points to.  a3 points to another the same A as otherA does,
but it can't be made to point to a different A and it can't alter the value
that it points to (while otherA can be altered to point to a different A and
you can use it to alter the value that it points to).

What I'd _like_ to be able to do is have reference which I can alter such that
it points to a different object but which does not allow me to alter what it
points to.  In C++, you have

const A* a1;  //variable pointer to a constant object.
A* const a2;  //constant pointer to a variable object
const A* const a3;  //constant pointer to a constant object

From what I can tell, you can do 2 of those in D with pointers:

const (A)* a1;  //variable pointer to a constant object.
const (A*) a3;  //constant pointer to a constant object

But I don't see how to get either a const pointer, so it lacks one of the three
with pointers.  With references, however, it lacks 2 of the three from what I
can tell.  It only has constant references to constant data.

I'm hoping that I just don't understand well enough how const works in D, but
right now, I don't see any way to get a variable reference to constant data. 
The missing constant pointer to variable data and constant reference to
variable data might be nice, but they don't matter anywhere near as much to me.

Is there a way to have variable reference to constant data in D?  I just don't
see it at the moment and it would be _really_ useful.
Nov 11 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jonathan M Davis wrote:
 Okay, I'm wondering if there is any way in D to have a reference to
 const.  As far as I can tell, if you use const on a reference, you
 get a constant reference to constant data.
 
 const A a1; const A a2 = new A(); A otherA = new A(); const A a3 =
 otherA;
 
 So, a1 points permanently to null.  You can't change what it points
 to (and of course you can't change null).  a2 points to an A which
 was constructed on assignment.  a2 can't be made to point to anything
 else and you can't change the value that it points to.  a3 points to
 another the same A as otherA does, but it can't be made to point to a
 different A and it can't alter the value that it points to (while
 otherA can be altered to point to a different A and you can use it to
 alter the value that it points to).
 
 What I'd _like_ to be able to do is have reference which I can alter
 such that it points to a different object but which does not allow me
 to alter what it points to.  In C++, you have
 
 const A* a1;  //variable pointer to a constant object. A* const a2;
 //constant pointer to a variable object const A* const a3;
 //constant pointer to a constant object
 
 From what I can tell, you can do 2 of those in D with pointers:
 
 const (A)* a1;  //variable pointer to a constant object. const (A*)
 a3;  //constant pointer to a constant object
 
 But I don't see how to get either a const pointer, so it lacks one of
 the three with pointers.  With references, however, it lacks 2 of the
 three from what I can tell.  It only has constant references to
 constant data.
 
 I'm hoping that I just don't understand well enough how const works
 in D, but right now, I don't see any way to get a variable reference
 to constant data.  The missing constant pointer to variable data and
 constant reference to variable data might be nice, but they don't
 matter anywhere near as much to me.
 
 Is there a way to have variable reference to constant data in D?  I
 just don't see it at the moment and it would be _really_ useful.

http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable Andrei
Nov 11 2008
next sibling parent reply Max Samukha <samukha voliacable.com.removethis> writes:
On Wed, 12 Nov 2008 00:59:18 -0600, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

Jonathan M Davis wrote:
 Okay, I'm wondering if there is any way in D to have a reference to
 const.  As far as I can tell, if you use const on a reference, you
 get a constant reference to constant data.
 
 const A a1; const A a2 = new A(); A otherA = new A(); const A a3 =
 otherA;
 
 So, a1 points permanently to null.  You can't change what it points
 to (and of course you can't change null).  a2 points to an A which
 was constructed on assignment.  a2 can't be made to point to anything
 else and you can't change the value that it points to.  a3 points to
 another the same A as otherA does, but it can't be made to point to a
 different A and it can't alter the value that it points to (while
 otherA can be altered to point to a different A and you can use it to
 alter the value that it points to).
 
 What I'd _like_ to be able to do is have reference which I can alter
 such that it points to a different object but which does not allow me
 to alter what it points to.  In C++, you have
 
 const A* a1;  //variable pointer to a constant object. A* const a2;
 //constant pointer to a variable object const A* const a3;
 //constant pointer to a constant object
 
 From what I can tell, you can do 2 of those in D with pointers:
 
 const (A)* a1;  //variable pointer to a constant object. const (A*)
 a3;  //constant pointer to a constant object
 
 But I don't see how to get either a const pointer, so it lacks one of
 the three with pointers.  With references, however, it lacks 2 of the
 three from what I can tell.  It only has constant references to
 constant data.
 
 I'm hoping that I just don't understand well enough how const works
 in D, but right now, I don't see any way to get a variable reference
 to constant data.  The missing constant pointer to variable data and
 constant reference to variable data might be nice, but they don't
 matter anywhere near as much to me.
 
 Is there a way to have variable reference to constant data in D?  I
 just don't see it at the moment and it would be _really_ useful.

http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable Andrei

class Widget { int x; int y() const { return a; } }: I'm not sure, if this example was intended to be compilable, but it won't because of a in y.
Nov 12 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Max Samukha wrote:
 On Wed, 12 Nov 2008 00:59:18 -0600, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Jonathan M Davis wrote:
 Okay, I'm wondering if there is any way in D to have a reference to
 const.  As far as I can tell, if you use const on a reference, you
 get a constant reference to constant data.

 const A a1; const A a2 = new A(); A otherA = new A(); const A a3 =
 otherA;

 So, a1 points permanently to null.  You can't change what it points
 to (and of course you can't change null).  a2 points to an A which
 was constructed on assignment.  a2 can't be made to point to anything
 else and you can't change the value that it points to.  a3 points to
 another the same A as otherA does, but it can't be made to point to a
 different A and it can't alter the value that it points to (while
 otherA can be altered to point to a different A and you can use it to
 alter the value that it points to).

 What I'd _like_ to be able to do is have reference which I can alter
 such that it points to a different object but which does not allow me
 to alter what it points to.  In C++, you have

 const A* a1;  //variable pointer to a constant object. A* const a2;
 //constant pointer to a variable object const A* const a3;
 //constant pointer to a constant object

 From what I can tell, you can do 2 of those in D with pointers:

 const (A)* a1;  //variable pointer to a constant object. const (A*)
 a3;  //constant pointer to a constant object

 But I don't see how to get either a const pointer, so it lacks one of
 the three with pointers.  With references, however, it lacks 2 of the
 three from what I can tell.  It only has constant references to
 constant data.

 I'm hoping that I just don't understand well enough how const works
 in D, but right now, I don't see any way to get a variable reference
 to constant data.  The missing constant pointer to variable data and
 constant reference to variable data might be nice, but they don't
 matter anywhere near as much to me.

 Is there a way to have variable reference to constant data in D?  I
 just don't see it at the moment and it would be _really_ useful.

Andrei

class Widget { int x; int y() const { return a; } }: I'm not sure, if this example was intended to be compilable, but it won't because of a in y.

Ouch. Thanks for the bug report. Andrei
Nov 12 2008
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmail.com> writes:
Andrei Alexandrescu wrote:
 
 http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable
 
 Andrei

Thanks for the info. It would be nice if variable references to constant data were built into the language, but as long as Rebindable works, at least it's possible to have them. However, it looks like I'm going to have to install dmd differently if I want to be able to use Rebindable. I'm using gentoo's official ebuild and it's on version 2.008. I had thought that that was the most recent version, but apparently not - and it looks like Rebindable has been added since then. Oh well, I'll get a newer version on my system one way or another. I'd prefer to be on the most recent version of dmd anyway, so this has pointed out to me that I'm quite a bit behind. In any case, thanks for the info. It'll be quite useful. And from the look of the page that you linked to, you're one of the folks that implemented it, so thanks for that too. - Jonathan M Davis
Nov 12 2008
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Jonathan M Davis wrote:
 Andrei Alexandrescu wrote:
 http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable

 Andrei

Thanks for the info. It would be nice if variable references to constant data were built into the language, but as long as Rebindable works, at least it's possible to have them. However, it looks like I'm going to have to install dmd differently if I want to be able to use Rebindable. I'm using gentoo's official ebuild and it's on version 2.008. I had thought that that was the most recent version, but apparently not - and it looks like Rebindable has been added since then. Oh well, I'll get a newer version on my system one way or another. I'd prefer to be on the most recent version of dmd anyway, so this has pointed out to me that I'm quite a bit behind. In any case, thanks for the info. It'll be quite useful. And from the look of the page that you linked to, you're one of the folks that implemented it, so thanks for that too. - Jonathan M Davis

Many wars were fought at one point about exactly this, and, indeed D 2.000-2.007 had it built into the language. Then Walter decided it would be too confusing for there to be both a head-const ("this thing is const") and a tail-const ("whatever this refers to is recursively const"). Thus, we ended up with the system we have today.
Nov 13 2008
parent Jonathan M Davis <jmdavisProg gmail.com> writes:
Robert Fraser wrote:

 
 Thanks for the info.  It would be nice if variable references to constant
 data were built into the language, but as long as Rebindable works, at
 least it's possible to have them.
 
 
 - Jonathan M Davis

Many wars were fought at one point about exactly this, and, indeed D 2.000-2.007 had it built into the language. Then Walter decided it would be too confusing for there to be both a head-const ("this thing is const") and a tail-const ("whatever this refers to is recursively const"). Thus, we ended up with the system we have today.

Well, it's certainly confusing enough in C++ and I don't see a nice, clean way to do it, so I can certainly understand deciding against having it built in - as nice as it might be if it were. - Jonathan M Davis
Nov 13 2008
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmail.com> writes:
Andrei Alexandrescu wrote:

 Jonathan M Davis wrote:
 Okay, I'm wondering if there is any way in D to have a reference to
 const.  As far as I can tell, if you use const on a reference, you
 get a constant reference to constant data.
 
 const A a1; const A a2 = new A(); A otherA = new A(); const A a3 =
 otherA;
 
 So, a1 points permanently to null.  You can't change what it points
 to (and of course you can't change null).  a2 points to an A which
 was constructed on assignment.  a2 can't be made to point to anything
 else and you can't change the value that it points to.  a3 points to
 another the same A as otherA does, but it can't be made to point to a
 different A and it can't alter the value that it points to (while
 otherA can be altered to point to a different A and you can use it to
 alter the value that it points to).
 
 What I'd _like_ to be able to do is have reference which I can alter
 such that it points to a different object but which does not allow me
 to alter what it points to.  In C++, you have
 
 const A* a1;  //variable pointer to a constant object. A* const a2;
 //constant pointer to a variable object const A* const a3;
 //constant pointer to a constant object
 
 From what I can tell, you can do 2 of those in D with pointers:
 
 const (A)* a1;  //variable pointer to a constant object. const (A*)
 a3;  //constant pointer to a constant object
 
 But I don't see how to get either a const pointer, so it lacks one of
 the three with pointers.  With references, however, it lacks 2 of the
 three from what I can tell.  It only has constant references to
 constant data.
 
 I'm hoping that I just don't understand well enough how const works
 in D, but right now, I don't see any way to get a variable reference
 to constant data.  The missing constant pointer to variable data and
 constant reference to variable data might be nice, but they don't
 matter anywhere near as much to me.
 
 Is there a way to have variable reference to constant data in D?  I
 just don't see it at the moment and it would be _really_ useful.

http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable Andrei

I would like to make the suggestion that Rebindable be discussed in the section of the documentation that discusses const and invariant ( http://www.digitalmars.com/d/2.0/const3.html ). It would make the situation clearer. Now it _is_ a part of phobos rather than a part of D itself, so I don't know if you want to discuss it in depth in the Language section of D's documentation, but I think that it would be quite helpful for those learning D. As it is, I don't find it entirely clear from that page that a const reference is const in the sense that both the reference and what it references are const, though arguably it follows from the transivity of const. Personally, I had to play around with some code to figure out in what way a const reference was const. In any case, I thank anyone who's worked on the documentation. While it certainly isn't perfect, I've found it to be a big help. - Jonathan M Davis
Nov 13 2008
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 Is there a way to have variable reference to constant data in D?  I
 just don't see it at the moment and it would be _really_ useful.

http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Rebindable

Small question regarding Rebindable that I've been meaning to ask. Does implicit assignment to a const(T) work, or does that require opImplicitCast? This would be useful not only for assignment, but also passing to functions which take const(T) instead of Rebindable!(T). Also, one other thing. A Rebindable!(T) only makes sense if T is const or invariant, but this is rather long winded: Rebindable!(const(A)) a; Would it make sense to have shortcuts to Rebindable that automatically apply const or invariant? something like: template tconst(T) { alias Rebindable!(const(T)) tconst; } Using whatever you think is best for a symbol name. Just something a little shorter. -Steve
Nov 13 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 "Andrei Alexandrescu" wrote
 Is there a way to have variable reference to constant data in D?  I
 just don't see it at the moment and it would be _really_ useful.


Small question regarding Rebindable that I've been meaning to ask. Does implicit assignment to a const(T) work, or does that require opImplicitCast? This would be useful not only for assignment, but also passing to functions which take const(T) instead of Rebindable!(T).

I think we'd need compiler support for opImplicitCast indeed.
 Also, one other thing.  A Rebindable!(T) only makes sense if T is const or 
 invariant, but this is rather long winded:
 
 Rebindable!(const(A)) a;
 
 Would it make sense to have shortcuts to Rebindable that automatically apply 
 const or invariant?  something like:
 
 template tconst(T)
 {
    alias Rebindable!(const(T)) tconst;
 }
 
 Using whatever you think is best for a symbol name.  Just something a little 
 shorter.

Better yet (or in addition to), we could make it a function so argument deduction takes care of everything. Rebindable!(const T) tailconst(const T r); Rebindable!(immutable T) tailimmutable(const T r); auto w = new Widget; auto w1 = tailconst(w); w1 = tailconst(new Widget); Andrei
Nov 13 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 Steven Schveighoffer wrote:
 Would it make sense to have shortcuts to Rebindable that automatically 
 apply const or invariant?  something like:

 template tconst(T)
 {
    alias Rebindable!(const(T)) tconst;
 }

 Using whatever you think is best for a symbol name.  Just something a 
 little shorter.

Better yet (or in addition to), we could make it a function so argument deduction takes care of everything. Rebindable!(const T) tailconst(const T r); Rebindable!(immutable T) tailimmutable(const T r); auto w = new Widget; auto w1 = tailconst(w); w1 = tailconst(new Widget);

These could be useful. Also, another reason for having a rebindable type is that you don't have to initialize it upon declaration, so having a shorter type for declaration would still be beneficial. -Steve
Nov 13 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 "Andrei Alexandrescu" wrote
 Steven Schveighoffer wrote:
 Would it make sense to have shortcuts to Rebindable that automatically 
 apply const or invariant?  something like:

 template tconst(T)
 {
    alias Rebindable!(const(T)) tconst;
 }

 Using whatever you think is best for a symbol name.  Just something a 
 little shorter.

deduction takes care of everything. Rebindable!(const T) tailconst(const T r); Rebindable!(immutable T) tailimmutable(const T r); auto w = new Widget; auto w1 = tailconst(w); w1 = tailconst(new Widget);

These could be useful. Also, another reason for having a rebindable type is that you don't have to initialize it upon declaration, so having a shorter type for declaration would still be beneficial.

Good argument. Now, finding the right names is the eternal challenge. TailConst!(T), TailImmutable!(T)? Other, perhaps shorter, ideas? Andrei
Nov 13 2008