Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A container might have an isEmpty function, and if the pointer is nil, that is probably more empty than not empty (though personally I don't believe either answer makes sense). "[x isEmpty]" might be more appropriate than "[x count]==0" for a list-type container.

I always check for nil explicitly, personally. It sidesteps any question of whether the method makes sense in the nil case. And sending messages to nil can't work in general, because the return value could be a struct.



Cheers for the counter-example.

I agree there isn't really a sensible answer for [nil isEmpty].

There are two uses of isEmpty I can think of.

    if ([container isEmpty]) {
        [container addItem:item];
    }
We want to add an item to an empty container. If it's nil, we don't add an item to it; that seems okay.

    if (![container isEmpty]) {
        Item item = [container getItemAt:0];
        [item doSomething];
    }
We check there will be an item before we get a value out of it. This one would cause issues.

NSArray doesn't have an isEmpty method. I wonder if this is one of the reasons why, or if it's just something like wanting to keep the interface small.

[Edit] You can of course invert the logic. Using [container hasItems] in the two examples above would function just fine. While isEmpty seems to be the variant used everywhere, hasItems doesn't seem too unnatural.


NSArray has a constant-time size query, so you might as well do "[x count]==0". If you had a linked list type structure, though, you might just have next/prev pointers in your list object, making a size query an O(N) operation. (The C++ STL provides an "empty()" function in its containers for presumably this reason. It has some containers that have to be implemented as linked lists or trees, meaning there's the possibility that "x.empty()" to be much more efficient than "x.size()==0". Not sure how often implementations take advantage of this, mind.)

As for how you'd use it, I've pretty much always used it for early outs:

    if(items.empty()) return NULL;
    return &items[items.size()%rand()];
or for filling in caches:

    if(items.empty()) return NULL;

    if(cache.empty()) { /* fill cache */ }

    assert(cache[index].underlying_item==items[index]);
    return cache[index].some_other_data;
So it always ends up being tested positively. Or it does if you code like me, anyway :) (I make no statement about whether you should or not.)


I dunno. I think a nil container is neither empty nor full, it's nil. But trying to reason about 3VL in an environment that doesn't support it is … trying.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: