views:

568

answers:

5

I know this has been discussed many times, but I am not sure I really understand why Java and C# designers chose to omit this feature from these languages. I am not interested in how I can make workarounds (using interfaces, cloning, or any other alternative), but rather in the rationale behind the decision.

From a language design perspective, why has this feature been declined?

P.S: I'm using words such as "omitted", which some people may find inadequate, as C# was designed in an additive (rather than subtractive) approach. However, I am using such words because the feature existed in C++ before these languages were designed, so it is omitted in the sense of being removed from a programmer's toolbox.

+7  A: 

I guess primarily because:

  • it can't properly be enforced, even in C++ (you can cast it)
  • a single const at the bottom can force a whole chain of const in the call tree

Both can be problematic. But especially the first: if it can't be guaranteed, what use is it? Better options might be:

  • immutable types (either full immutability, or popsicle immutability)
Marc Gravell
+13  A: 

In this interview, Anders said:

Anders Hejlsberg: Yes. With respect to const, it's interesting, because we hear that complaint all the time too: "Why don't you have const?" Implicit in the question is, "Why don't you have const that is enforced by the runtime?" That's really what people are asking, although they don't come out and say it that way.

The reason that const works in C++ is because you can cast it away. If you couldn't cast it away, then your world would suck. If you declare a method that takes a const Bla, you could pass it a non-const Bla. But if it's the other way around you can't. If you declare a method that takes a non-const Bla, you can't pass it a const Bla. So now you're stuck. So you gradually need a const version of everything that isn't const, and you end up with a shadow world. In C++ you get away with it, because as with anything in C++ it is purely optional whether you want this check or not. You can just whack the constness away if you don't like it.

BobbyShaftoe
MSalters
+1  A: 

As to why they did it those involved have said so:

http://blogs.msdn.com/ericgu/archive/2004/04/22/118238.aspx http://blogs.msdn.com/slippman/archive/2004/01/22/61712.aspx also mentioned by Raymond Chen http://blogs.msdn.com/oldnewthing/archive/2004/04/27/121049.aspx

In a multi language system this would have been very complex.

ShuggyCoUk
+1  A: 

As for Java, how would you have such a property behave? There are already techniques for making objects immutable, which is arguably a better way to achieve this with additional benefits. In fact you can emulate const behaviour by declaring a superclass/superinterface that implements only the methods that don't change state, and then having a subclass/subinterface that implements the mutating methods. By upcasting your mutable class to an instance of class with no write methods, other bits of code cannot modify the object without specifically casting it back to the mutable version (which is equivalent to casting away const).

Even if you don't want the object to be strictly immutable, if you really wanted (which I wouldn't recommend) you could put some kind of 'lock' mode on it so that it could only be mutated when unlocked. Have the lock/unlock methods be private, or protected as appropriate, and you get some level of access control there. Alternatively, if you don't intend for the method taking it as a parameter to modify it at all, pass in a copy of that object, or if copying the entire object is too heavyweight then some other lightweight data object that contains just the necessary information. You could even use dynamic proxies to create a proxy to your object that turn any calls to mutation methods into no-ops.

Basically there are already a whole bunch of ways to prevent a class being mutated, which let you choose one that fits most appropriately into your situation (hint: choose pure immutability wherever possible as it makes the object trivially threadsafe and easier to reason with in general). There are no obvious semantics for how const could be implemented that would be an improvement on these techniques, it would be another thing to learn that would either lack flexibility, or be so flexible as to be useless.

That is, unless I've missed something, which is entirely possible. :-)

Andrzej Doyle
One could say that "const" turns a mutable object into an immutable with no extra code. With immutable types, you often end up with a second "builder" type. -- Generally I like the declarative expressiveness of "const"; though I agree it's a can of worms.
peterchen
A: 

Java have its own version of const; final. Joshua Bloch describes in his Effective Java how you effectively use the final keyword. (btw, const is a reserved keyword in Java, for future discrepancies)

Schildmeijer
final is massively different from const, it is but a shadow of it.readonly in c# is equivalent to final in java except it cannot be applied to local variables (a shame IMO). const is also a reserved word in c# for just the same reason
ShuggyCoUk