Logical const

Michel Fortin michel.fortin at michelf.com
Sun Nov 28 10:36:08 PST 2010


On 2010-11-28 09:50:53 -0500, Peter Alexander 
<peter.alexander.au at gmail.com> said:

> Surely I'm not the only person that finds something *incredibly* wrong 
> with this!?

I don't find it wrong, but it can certainly be an annoyance. Most other 
languages manage without any concept of 'const' at all. How do they do 
it? One idiom is to implement logical constness as part of the type. 
For instance, you could have two classes:

	class Matrix {
		private float[4][4] values;
		float getValue(uint i, uint j) {
			return values[i][j];
		}
	}
	class MutableMatrix : Matrix {
		void setValue(uint i, uint j, float value) {
			values[i][j] = value;
		}
	}

The first class is *logically* immutable, in the sense that it contains 
only accessors. The derived one adds methods capable of changing the 
content. If a function accepts a Matrix, it can't change the matrix's 
logical content even if you give it a MutableMatrix. The method 
signatures thus become:

	Matrix getInverse(Matrix m) { ... }

Short of casting m to a MutableMatrix, logical constness is enforced. 
Here's the mutable parameter version:

	void invertInPlace(MutableMatrix m) { ... }

And now you have your constness garenties.

Note that you can implement a similar pattern at the struct level using 
"alias X this":

	struct Matrix {
		private float[4][4] values;
		float getValue(uint i, uint j) {
			return values[i][j];
		}
	}

	struct MutableMatrix {
		Matrix matrix;
		alias matrix this;

		void setValue(uint i, uint j, float value) {
			values[i][j] = value;
		}
	}

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list