On Fri, Sep 20, 2013 at 05:42:03PM +0200, Joseph Rushton Wakeling wrote: > On 20/09/13 17:22, H. S. Teoh wrote: > >Which makes it even more confusing, since newbies would probably > >equate arrays (the container) with ranges from their frequent use in > >range examples. > > Yes, it's completely non-obvious. I think the first time I realized > the range/container distinction was when I tried experimentally > replacing some built-in arrays with std.container.Array and > discovered that I couldn't use them in a foreach loop.
Sad to say, I encountered a good number of Phobos bugs caused by the conflation between built-in arrays and ranges. Code would inadvertently assume array behaviour on ranges, and break when you pass in a non-array range. Some of these have been fixed; I'm pretty sure there are still more lurking around. > >Perhaps it's more useful to think of T[] not as an array per se, but > >as a *slice* of the underlying array data which is managed by > >druntime. I think I'm OK with saying that arrays (i.e. the underlying > >data) are containers, while slices (what we think of today as > >"arrays") are ranges. > > It's not a bad description, but I'm not sure that takes into account > the const(T[]) case. Actually, it helps you understand the const(T[]) case. To iterate over a const array, you need a range over it (i.e., a slice); and indeed, writing arr[] on an array of type const(T[]) gives you a tail-const slice of type const(T)[], which *is* an iterable range. The confusion really just stems from the conflation between T[] and a range over T[] in the non-const case. T -- People tell me I'm stubborn, but I refuse to accept it!
