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