Why I think Array#some is wrong

Lodash v4 was recently released, and it removed any as an alias to some. I think I get it: Array#some is a thing and Array#any is not, so people should get use to using the "real" (albeit wrapped in this case) method. I was slightly disappointed by this. I always choose any over some when using lodash, so now I have to go change references in old code when I want to update to lodash v4 (although I actually wrote a thing that puts those aliases back so . . . huzzah, open source!). But this did get me to thinking . . . why is it that I prefer any? I came up with four reasons. I find these reasons compelling enough that I posit that the ECMAScipt standard got it wrong when they chose Array#some. Alas, that ship has sailed and even if it hadn't, I don't have a say in it. Nonetheless, here are my entirely compelling and irresistibly logical arguments in favor of Array#any over Array#some.

1. Any is semantically correct

This is based on the premise that "any" and "some" are semantically different. And they really are. If I ask if "some" apples in a bag are moldy, the meaning is different than if I ask if "any" are moldy. In the latter case, I may simply be selective when picking one out, but in the former case, if they answer is yes, I'm probably throwing the whole bag out. Basically, "some" suggests more than one, whereas "any" could mean one, or it could mean more. Additionally, "some" also implies "less than all" but "any" could also be "all." Even the ECMAScipt standard agrees. The explanation of the return value of Array#some on MDN says, "This function returns true if the callback function returns true for any array element; otherwise, false." Note the use of "any" in that sentence. Try to rewrite it using "some" without changing the meaning. It doesn't work.

2. Any is implementationally correct

I've never written an any/some implementation, but I imagine it would go something like this:

function any (list, test) {  
  var result = false;
  for (var i = 0; i <= list.length; i++) {
    result = test(list[i], i, list);
    if (result) {
      break;
    }
  }
  return result;
}

Basically, if any item in the list evaluates to true, break off the loop (i.e. don't process any more items) and return true. My idea of what "some" would look like is this:

function some (list, test) {  
  var results = 0;
  for (var i = 0; i <= list.length; i++) {
    var result = test(list[i], i, list);
    if (result) {
      results++;
    }
  }
  return results > "?????" ? true : false;
}

The problem, of course, is how many truthy results are necessary to make up some. This is hyperbole of course. I'm sure the some implementation looks roughly like my any function, but the point is that that doesn't make sense.

Any is usage correct

A developer typically wants to know if any item in a list is like X. I can't think of a case where they'd want to know if some of the items in a list are like X. It's understood that "This will be true if a single item is like this. Or if more than one is like this. Or if all of them are." I know Do What I Mean is a Perl thing, but . . . seriously, do what I mean! I mean, is any item in this list mod 2 equal to 0?

Any is diametrically opposed to every

The correctly named Array#every suggests that every item in a list must pass a truth test for the whole expression to be true. I don't know that any and every are opposites but in programming, they are certainly inversely analogous. "Some," on the other hand, is more closely analogous to "all" (which incidentally was the lodash alias to "every"). So why do we have every and some? It should be either every/any or all/some. The first set is more in line with the meaning of the functions.

Arguments in favor of some

It's the actual standard. Now we're all stuck wondering just how many of our apples are moldy.

comments powered by Disqus