www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - rebind of const class variables

reply "qqiang" <wqzhiep gmail.com> writes:
I am writing a tree data structure, and I have the following code:

```D
final class Node {
     private {
	int val_;
	Node parent_;
	Node left_;
	Node right_;
     }

      property
     const(Node) maximum() const {
	auto ret = this;
			
	while (ret.right_) {
	    ret = ret.right_;
	}
			
	return ret;
     }
}
```

It failed to compile and complaint that `cannot modify const 
expression ret`。

Since `ret` is just a binding to a const class object, why can't 
I rebind it to another const class variable?

Must I use pointers to cope with this?

Thx
Jan 20 2015
next sibling parent "Mathias LANG" <geod24 gmail.com> writes:
On Tuesday, 20 January 2015 at 09:29:46 UTC, qqiang wrote:
 I am writing a tree data structure, and I have the following 
 code:

 ```D
 final class Node {
     private {
 	int val_;
 	Node parent_;
 	Node left_;
 	Node right_;
     }

      property
     const(Node) maximum() const {
 	auto ret = this;
 			
 	while (ret.right_) {
 	    ret = ret.right_;
 	}
 			
 	return ret;
     }
 }
 ```

 It failed to compile and complaint that `cannot modify const 
 expression ret`。

 Since `ret` is just a binding to a const class object, why 
 can't I rebind it to another const class variable?

 Must I use pointers to cope with this?

 Thx
You are looking for
Jan 20 2015
prev sibling next sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, January 20, 2015 09:29:45 qqiang via Digitalmars-d-learn wrote:
 I am writing a tree data structure, and I have the following code:

 ```D
 final class Node {
      private {
   int val_;
   Node parent_;
   Node left_;
   Node right_;
      }

       property
      const(Node) maximum() const {
   auto ret = this;

   while (ret.right_) {
       ret = ret.right_;
   }

   return ret;
      }
 }
 ```

 It failed to compile and complaint that `cannot modify const
 expression ret`。

 Since `ret` is just a binding to a const class object, why can't
 I rebind it to another const class variable?

 Must I use pointers to cope with this?
The thing to remember is that const is transitive, and when you have const MyClass foo; the reference itself is const, not just what it refers to. And the type system doesn't have a way to represent a mutable reference to a const class object, because it has no way of representing classes separately from references to them. The two are, for better or worse, very much conflated as far as the language is concerned. Pointers don't have that problem. e.g. const(MyStruct)* foo; but if you did const(MyClass)* foo; you'd just end up with a pointer to a const reference to a class object and not a pointer to a const class object. Rebindable works around the problem by being a mutable holder for the const reference to the class. It's a bit a annoying and clunky, but it's a side effect of how there really isn't any way in the language to represent class objects separately from the references to them. - Jonathan M Davis
Jan 20 2015
prev sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Tue, 20 Jan 2015 09:29:45 +0000
qqiang via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 I am writing a tree data structure, and I have the following code:
=20
 ```D
 final class Node {
      private {
 	int val_;
 	Node parent_;
 	Node left_;
 	Node right_;
      }
=20
       property
      const(Node) maximum() const {
 	auto ret =3D this;
 		=09
 	while (ret.right_) {
 	    ret =3D ret.right_;
 	}
 		=09
 	return ret;
      }
 }
 ```
=20
 It failed to compile and complaint that `cannot modify const=20
 expression ret`=E3=80=82
=20
 Since `ret` is just a binding to a const class object, why can't=20
 I rebind it to another const class variable?
=20
 Must I use pointers to cope with this?
Jonathan explains it very well. i can add the only thing: don't use `const` until you forced to. ;-) C++ programmers tend to "help compiler" with const methods and so on. just don't do that in D until you become friends with D constness. sure, you can cast `const` away in your code, but using `cast` is a good sign of taking the wrong way.
Jan 20 2015
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
ketmar:

 Jonathan explains it very well. i can add the only thing: don't 
 use `const` until you forced to. ;-)
In D use immutable (or const) everywhere you can. Possibly mark as immutable everything doesn't need to mutate.
 sure, you can cast `const` away in your code, but using `cast` 
 is a good sign of taking the wrong way.
Casting away a const is quite dangerous in D because if you later mutate the data, you will probably have bugs. Bye, bearophile
Jan 20 2015
parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Tue, 20 Jan 2015 14:45:26 +0000
bearophile via Digitalmars-d-learn <digitalmars-d-learn puremagic.com>
wrote:

 ketmar:
=20
 Jonathan explains it very well. i can add the only thing: don't=20
 use `const` until you forced to. ;-)
=20 In D use immutable (or const) everywhere you can. Possibly mark=20 as immutable everything doesn't need to mutate.
i didn't tell a word about `immutable`. ;-) but `const` transitiveness confusing newcomers alot. eventually they will catch it and then they will see how my advice is not applicable to 'em anymore. but until then i believe that they better don't use `const` at all instead of becoming constantly frustrated with it's "non-friendly" behavior.
Jan 20 2015