const?? When and why? This is ugly!

Steven Schveighoffer schveiguy at yahoo.com
Mon Mar 9 10:13:33 PDT 2009


On Sun, 08 Mar 2009 19:24:32 -0700, Andrei Alexandrescu wrote:

> Steve Schveighoffer wrote:
>> On Sun, 08 Mar 2009 17:24:09 -0700, Walter Bright wrote:
>> 
>>> Derek Parnell wrote:
>>>> I know that a better way to code this example would have been to use
>>>> the .idup functionality, but that is not the point. I relied on the
>>>> compiler ensuring that everything declared as immutable would not be
>>>> modified. The compiler failed.
>>> It is the same issue. When you use a cast, you are *explicitly*
>>> defeating the language's type checking ability. It means that the onus
>>> is on the one doing the cast to get it right.
>> 
>> Except when you want invariant data, then cast is *required*.
> 
> Not at all. Calling idup (or, more elegantly, to!TargetType) or
> assumeUnique under the circumstances documented by assumeUnique are all
> safe. Sometimes the price for added safety is one extra copy. But the
> added safety is worth it more often than not.

idup is not a viable option in certain cases, if memory usage or 
performance are important.  It might not even be available if the object 
in question doesn't implement a function that does it.  assumeUnique 
suffers from the same problems as casting.  It just avoids any potential 
casting that changes types instead of constancy.

I agree that in 90% of cases, using invariant strings is beneficial, and 
not a burden.  I think the arguments against are for those small cases 
where performance is significantly hindered, and having a library which 
uses string where it should use in char[] makes life difficult for those 
cases.  I understand you are fixing this, so that is good.

> 
> As far as signatures of functions in std.string, I agree that those not
> needing a string of immutable characters should just accept in Char[]
> (where Char is one of the three character types). That should make
> people using mutable and immutable strings equally joyous.
> 

What might be useful is coming up with an alias for char[], like mstring 
or something that shakes off the notion that a mutable char[] is not a 
string.

>> At that
>> point, it is a language feature, not a defeat of the typesystem.  I
>> think there is some merit to the arguments presented in this thread,
>> but I don't think the answer is to get rid of invariant.  Perhaps make
>> the compiler more strict when creating invariant data?  I liked the
>> ideas that people presented about having unique mutable references
>> (before and in this thread).  This might even be solvable in a library
>> given all the advances in structs.
> 
> Unique has been discussed extensively a couple of years ago when we were
> defining const and immutable. We decided to forgo it and go with
> assumeUnique.

I see in your reply to walter that it could be done with some bug fixes, 
I think this should be an important step to make.

>> So it's not exactly the same issue, because in one you are doing
>> something totally useless and stupid.  And in the other, it is a
>> language *requirement* to use casting to get invariant data.  However,
>> in both cases, the onus is on the developer, which sucks in the latter
>> case...
> 
> NO. It is not a language requirement. If what you have is mutable data
> and someone else wants immutable data, make a copy.

Unless copying hinders performance so much that you would rather take the 
safety hit and start casting.  Imagine having to copy every message that 
was received on a network stream just so you could use string functions 
on it.  Or having to duplicate all the data read into a small buffer from 
a file just to search for strings in it.

>> Walter: Use invariant when you can, it's the best! User: ok, how do I
>> use it?
>> Walter: You need to cast mutable data to invariant, but it's on you to
>> make sure nobody changes the original mutable data.  Casting
>> circumvents the typesystem, so the compiler can't help you. User: :(
> 
> Casts to immutable should not be part of most programs.

assumeUnique is a cast.  You have not avoided that.  The extra steps it 
goes through is not enough to quiet this discussion.  We are not talking 
about using assumeUnique or casting everywhere in a program.  We are 
talking about how difficult it is to call functions that take strings 
when they should take const(char)[] (a practice that is going to continue 
since the string label has been attached to immutable(char)[] only) in 
the rare cases when you need the functions.

-Steve



More information about the Digitalmars-d mailing list