const?? When and why? This is ugly!

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Mar 6 12:00:59 PST 2009


Burton Radons wrote:
> A more accurate way would be for the string type to be "const (char)
> []", and for functions which retain strings that can't change to take
> "invariant (char) []". That makes pretty good claims about the nature
> of the string, but it would clearly result in lots of cast
> management.

I use that all the time, it's a great idiom. What cast management needs 
to be done? What I need to do is occasionally insert an .idup on the 
client side because the callee wants a copy. So that's that.

> I think all these problems boil down to the fact that invariant tells
> you about the container rather than the object itself; but whether
> the object actually is invariant is totally independent of the
> container. The genius of D 1.0's const is that it makes an actual,
> actionable true statement about the object. That was a HUGE benefit.
> This tries to push it back into C territory and I don't think it
> works.

I don't think I understand most of this, possibly because some of it is 
wrong. D2's immutable does offer a solid guarantee about what's going on 
and offers a programming model that makes it easy to write correct code 
without undue aliasing. So C doesn't quite enter into the picture there.

Objects in a container being invariant tell a lot about the container. 
That property makes the container shareable without a risk.

> I don't buy that this is going to lead to any MP bonuses either.

Wait and see.

> Const has turned into a form of the sufficiently complex compiler
> fallacy, the cure for any ail. But if you can cast const on or off,
> then any declaration you make about the mutability of the data is
> going to be wrong at some point, and compilers can't sometimes build
> the right code.

In D you will be able to break any design with a cast, unless you use 
the not-yet-defined D2 which disallows all risky casts. So the fact that 
you can cast const away is hardly changing anything.

>>> It doesn't affect pure at all, because pure can be passed
>>> invariants which are just casted - the compiler needs to use
>>> rules which are a hell of a lot more binding than anything we can
>>> provide it to make these determinations. Now that const is not a
>>> storage class, it's actually not possible to declare function
>>> variables which should be stored in read-only memory (unless if
>>> it's encoded somewhere in the thirty or so combinations you can
>>> use), which also damages pure. It's a lot more confusing to deal
>>> with const data altogether than it used to be.
>>> 
>>> When I switched from D 1.0 to 2.0 I tried several times to port
>>> some large pieces of code over and ultimately gave up, just as
>>> everyone has given up trying to do it in C++. It's a hard task
>>> moving code through that kind of change.
>>> 
>>> I've learned to handle it but I would really like to not be
>>> fighting the compiler all the time. Is that what I'm supposed to
>>> be doing here, really?
>> Can you be more specific about what was stimying you, as perhaps we
>> can think of a solution.
> 
> Exactly the same thing as trying to do it in C++. You're stuck
> iteratively applying const to pretty much everything, and applying
> tons of casts to get the compiler to shut up.

But this is misusing const. It means it didn't belong there in the first 
place. Const (and immutable) in D appear less frequently than in C++ 
because they provide superior guarantees.

> Oh, and templates. Templates that have nothing to do with any of
> these matters keep on having to be changed to appease the const god.
> Dealing with templates when you're doing really crazy stuff's bad
> enough without having that around.

Agreed, qualifiers do make templates a tad harder to define. Fortunately 
std.traits.Unqual (to be released) can be helpful there.


Andrei



More information about the Digitalmars-d mailing list