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