Writing const-correct code in D

xs0 xs0 at xs0.com
Wed Mar 8 08:44:27 PST 2006


Don Clugston wrote:
> Johan Granberg wrote:
>> xs0 wrote:
>>> So, would a system like this be acceptable?
>>>
> 
> I think having seperate overloads for const and non-const parameters is 
> a design mistake in C++. I see C++ 'const' as a compile-time contract, 
> not a type. IMHO, overloading const vs non-const is like overloading 
> functions based on their contracts.
> 
> I suspect that 'const' has exaggerated importance to those of us from a 
> C++ background, because it's almost the only contract that C++ provides.
> Maybe the solution to 'const' is a more general compile-time contract 
> mechanism.

Well, stepping back a little, it is indeed about contracts, specifically 
preventing one function/thread to modify data from another 
function/thread (where the idea is not to offer any absolute guarantees, 
but rather to make it impossible to write bad code unintentionally). 
Unlike you, though, I think this type of contract is so common, it 
deserves a special mechanism.

In any case, two questions arise
1) what exactly does it mean to modify something (specifically a 
composite type like an object)
2) how to design language support so it is able to express those 
contracts in a simple manner (it should be both simple to use and simple 
to implement)

Considering it's impossible for the compiler to know what you consider 
an object's state, you'll have to annotate fields and methods in some 
cases, one way or another. Considering that, the defaults proposed seem 
reasonable to me:
- fields are considered to contribute to object's state, unless 
specified otherwise (as most fields are indeed part of state)
- methods are inferred to read/modify the state based on which fields 
they modify

Just looking at random classes in my workspace, I'd say those will get 
at least 95% of classes correct, without the coder doing any work at all.

The only thing remaining is to specify which of the references you want 
to be read-only (which again you need to do in any case). There are 
basically two cases that need to be covered (in others, mutability is 
more or less implied):
- a function wants to prevent modification of the return value (both 
using "return" or "out")
- a caller wants to prevent modification of "in" parameters

Again, I see no other solution than to annotate both, but unlike with 
C++, inference on mutability of in parameters will mean that you won't 
have to annotate each and every in parameter which remains unchanged, 
but rather only those where it is not obvious.

Finally, as far as "two types per type" are concerned, it was more of an 
implementation detail than anything else - by treating most of the 
compilation this way, you can already use existing mechanisms for 
overload resolution etc., there definitely is no need for actually 
having two types. Readonliness is just an attribute of a reference.


xs0



More information about the Digitalmars-d mailing list