On Wednesday, March 21, 2012 15:46:12 Steven Schveighoffer wrote: > On Wed, 21 Mar 2012 14:33:58 -0400, Jonathan M Davis <jmdavisp...@gmx.com> > > wrote: > > On Wednesday, March 21, 2012 15:54:51 Daniel Murphy wrote: > >> FWIW, I would rather see `if (array)` translated to `if (array.length)` > >> and > >> this become the recomended way to check if an array is empty. Wouldn't > >> that > >> remove the dependency on std.array for most of the cases? > > > > The problem with checking whether length == 0 is that it's inefficient > > for some > > containers, so it's generally good practice to use empty rather than > > length. > > But we are specifically talking about arrays, not containers in general. > Containers in general are not defined by the language.
I know that. Much point is that length == 0 is a bad thing to do in general, because it's ineffecient with some containers. The language itself is pretty much irrelevant as far as that goes. As such, I'd argue in pretty much _any_ language that using length == 0 instead of empty is _not_ a good habit to be in. Doing it with arrays will make it much more likely that you'll end up doing it with containers without thinking about it. On the other hand, if you're in the habit of _always_ using empty rather than length == 0, then you don't have the problem. > > And while length == 0 is fine for arrays, it promotes bad habits in > > general, so > > I'm against it and think that code should pretty much always use empty > > rather > > than length == 0. > > I think you may misunderstand the proposal. if(array) translating to > if(array.length) is *only* for arrays, not for general types. No. I understand just fine. My point is that doing length == 0 for _any_ type of container is bad, because it promotes bad habits and leads to inefficient code for containers where it _does_ matter. So, I'd argue that if you should always be using empty rather than length == 0 - even with arrays - which currently means that you're almost always importing std.array. Having empty in object.d certainly isn't necessary, but it mitigates the problem, because then you don't have to import it if all you care about is empty. if(array) is a special case. If we want to change it to translate to if(array.length) then fine. That's all tied up in the insanity of an empty array and a null array being considered equal. But even if you want to use that syntax, it only mitigates the length == 0 vs empty issue for arrays rather than eliminating, because it only works directly in if statements and the like. The issue of choosing length == 0 vs empty still remains in many cases. And actually, I'd personally shy away from the if(array) syntax regardless simply because of the inherent ambiguity. Even if the language clearly defines it, I believe that it's the sort of thing that programmers are likely to misunderstand - particularly since if(var) checks for null with all of the other reference types. Experienced D programmers will know, but since newbies probably won't I'd consider it a code smell. I think that muddling null and empty was D's largest mistake with arrays and tend to think that any code that isn't explicit about it is asking for trouble if nothing else because the odds aren't low that the programmer did one thing when they meant another, because they didn't understand how null and empty arrays interact (e.g. arr == null is _always_ a bad sign IMHO). > I don't see why defining empty in object.d is necessary for things that > don't involve ranges at all. It's not necessary, but it would be nice. empty isn't just a range thing. Containers in general use it (across many languages whether ranges are involved or not), and for the reasons that I've already given, I don't think that length == 0 should ever be used in code. So I'd argue that you should always be using empty, which means importing std.array all the time if empty isn't in object.d, even if you _aren't_ doing range-based operations. Now, range-based operations are so common that you pretty much have to import std.range in most code anyway, so it really isn't all that much of a burden to have to import std.array or std.range to get at empty, but putting it in object.d definitely provides some benefit. So, I'm not sure that I care all that much whether std.array.empty gets moved to object.d or not, but I'd strongly argue that code should import std.array and use it rather than checking length == 0 as long as empty is in std.array rather than in object.d. So, if putting empty in object.d promotes the use of empty over length == 0, I'm all for it. - Jonathan M Davis