Jonathan M Davis wrote: > On Saturday 15 January 2011 09:02:55 Lutger Blijdestijn wrote: >> Jonathan M Davis wrote: >> > On Thursday 13 January 2011 21:21:06 %u wrote: >> >> Hi, >> >> >> >> I've noticed that some functions, such as algorithm.endsWith, don't >> >> work with constant arrays. Is this a bug, or is there a reason behind >> >> it? It forces the user to perform dangerous casts to avoid object >> >> creation, and it doesn't seem like the functions actually need to >> >> perform any manipulations. >> > >> > Phobos doesn't really deal with const or immutable correctly at this >> > point. A number of things which should be able to handle const or >> > immutable can't. And then there are things which you'd think _should_ >> > be able to but can't because of the transivity of const and immutable. >> > There are a number of outstanding bugs related to const and immutable >> > which makes dealing with them at times a bit of a pain if not outright >> > impossible. It's on the list of things to be focused on after the >> > 64-bit port of dmd is done. >> > >> > As it stands, there are a number of algorithms which just won't work >> > with const or immutable arrays. >> > >> > Regardless, a fully const array is never going to work with a function >> > like endsWith() for the simple reason that such functions have to >> > actually be able to process the range that they're given, and if the >> > range is const, you can't call popFront() or popBack() on it, so it >> > just isn't going to work. >> > >> > Now, if you take a _slice_ of a const array, it should work, because >> > while the elements of the array will remain const, the slice itself >> > won't be, so endsWith() can process it. >> > >> > - Jonathan M Davis >> >> A slice won't work because it is still const(T[]). It can implicitly >> convert to const(T)[], but I believe that is a bug currently. > > No, I'm pretty sure that that isn't a bug. A slice is a new array. A > const(T)[] that points to the same elements of an array that's const(T[]) > can't change the elements any more than the const(T[]) can. So, const is > not violated for the elements. And since the slice is a new array, the > fact that you can alter the slice itself is completely valid. You can > resize the slice or set to an entirely different block of memory or > whatever, at it won't affect the original array, so it does not violate > the const-ness of the const(T[]) array.
Yes, I agree the behavior is correct, it's indeed the inconsistency I was referring to. At this moment I'm not sure how it is gonna work out. I failed searching bugzilla, but relying on this behavior would make me a bit nervous. About the slicing, this works: const(int[]) n = [1,2,3]; const(int)[] a = n[]; assert(endsWith(a, 3)); but this doesn't: auto b = n[]; assert(endsWith(b, 3)); In conclusion, you still have to 'convert' the array to a different type, even though casting is not required for arrays (and arrays only). otoh, treating a const array as a range doesn't make any sense in the first place, since ranges must be mutable by definition. Arrays *are* special in the sense that they act both as a container and 'iterator' over that container. > So, no, it's not a bug. The bug is that this sort of behavior doesn't work > for general ranges - just arrays - and that we don't currently have a > means of making it work with general ranges. It cripples const and > immutable ranges, but it doesn't cripple const and immutable arrays. > > - Jonathan M Davis
