Magnus Lidbom said:
If C++ style const is introduced, mutable is a necessity. The need for
lazy evaluation and similar techniques is far to common to leave
mutable out.
It is const. That's what immutable means. That any and all instances
of the class are const.
What I mean is that an immutable object is different from
public const MyObject o; An immutable object cannot be changed from the
outside, ever, where as in the way const works(as I understand it, again I'm
no C++ master) it is strictly a reference\variable\signature based system. I
consider these significantly different and deserving of different terms(and
keywords if both are to be added). Overall while const is more valuable as
its much harder to design for without extra support, immutability isn't
something to be ignored.
I don't see why C# could not give the same guarantees through a
compile time validation that C++ can. Could you elaborate on this?
To be entirely clear, the C# compiler would be expected to provide compile
time verification, thats a given in my mind. However, I don't feel that it
is enough. The runtime should provide the last-word guarentee, while the
language\compiler provides compiletime verification of its own source
against the contract provided by classes, but no deeper. The point of this
would be that *no* code could break const. Isn't that part of the point of
managed code, ?
Only if you consider bugs and undefined behavior to be OK.
Const can't stop programmers from making a mess when they break the
rules on purpose. That doesn't detract anything from the protection
and clarification that it can provide.
I agree, however, I simply don't feel such a thing as a competent programmer
exists(we all screw up and make bad choices once in a while), if we are
going to go ahead with const we may as well do it right. const *isn't* a
contract when applied to a reference, in the C++ style, it is more a
shelter. It protects the coder from making a mistake, but doesn't stop them.
I would like to see a form of const in C#\.NET that *is* a contract. A const
instance should always be constant.
For that matter, what I consider to be ok and what is a real contract are
very different things. For what I consider, documentation is strong enough,
I will read it and believe it(unless the code starts to show otherwise). A
real contract should be enforced by both the compiler and the runtime, not
something that can be circumvented so easily as C++ const can.
There is great need for all of those. They all make it easier for the
programmer to write safe code. In the case of access modifiers and
const they make contracts explicit and make it possible for the
compiler to verify that those contracts are not breached, at least not
without making the breach explicit through the use of a cast. This is
very valuable regardless of the competence of the programmer.
Would you say that a competent police officer doesn't need a west when
storming a building?
Please elaborate.
Much as I was saying above. It is a weak contract, if a contract at all, and
not something that should be in a system like .NET. This is one of the
fundamental differences between managed code and old C++. C++ doesn't offer
a good many of the other niceties of managed code and I simply think its
silly to decide to use a weak version of one concept simply out of laziness
or unwillingness to think of something new. Although it should have been in
the orignal version, const is something that should be done properly.
The fix is extremely simple, add const to the parameter declaration.
And do what exactly when you don't control that code?
Only if MyOtherMethod takes a non const MyType.
I should have specified that, but I meant to imply that MyOtherMethod
doesn't take const MyType as its parameter.
Making it impossible to cast away const would, as you say, require
modifications to the runtime. Unless I'm mistaken, it would in fact
require changing the runtime representation of a reference, doubling
its size from 32 bits to 64, and introducing another level of
indirection for each invocation of a member on a reference. I don't
think the consequences of such a change would be palatable. For
starters it would almost double the memory usage of most .Net
applications, and I'd expect a performance degradation across the
board.
I don't think there would be a nessecery increase in the size of a
reference. 32 bits will handle 4 billion references, which is impossible to
do with 32 bit hardware(16gigs of references alone), on 64 bit hardware you
have far more. It wouldn't be impossibleto carve off 2 or 3 bits from a
reference for flags, even if a reference is only 30 bits you end up with
about 1billion possible references, which is more than enough for *ANY*
application running on the framework, even 500 million is probably
sufficent(at this numbers, the size of reference * the number of references
alone supercedes .NET allocable memory, leaving no room for the actual
objects). While such a thing isn't nessecerily feasible, it would work
without any of the problems. It also assumes the top 2 bits aren't already
used for something.
On 64 bit systems, the maximum number of references at 60 bits would be well
beyond memory capacity(I don't think many 64 bit chips actually use 64 bit
addressing).
Ideally, it would be possible to cast *to* const, but not from. The
orignator of an object should have the choice as to where it wants to pass
const and non-const references. With the system above such a cast would be a
bitmask, just by setting the first bit.