March 09, 2009Re: const?? When and why? This is ugly!
Posted in reply to Andrei Alexandrescu
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