Tuesday, 8 April 2014

listContains() is almost certainly not what you mean to be using

G'day:
This topic is fished from a "conversation" (if one will permit it to be called that) from Twitter yesterday. I'm writing this so that it will show up in Google results if people are wondering about the function. Bottom line: if ever you find yerself using listContains(), there's a very very good chance you actually ought to be using listFind(), and you are overlooking a subtle difference between the two.


Here's some code:

days = "Tuesday,yesterday,day,another day"
containedAt =  listContains(days, "day")
foundAt = listFind(days, "day")

dump({
    "Using listContains()"    = containedAt,
    "Using listFind()"        = foundAt
})

And its result:

Struct
Using listContains()
number1
Using listFind()
number3

As per the docs - the things that people seldom read, it seems - listContains() returns the index of the first list element which contains the sought-after string; listFind() returns the index of the first list element which equals the sought-after string. It's a subtle difference.

Once seldom wants to perform the operation the functionality of listContains() caters for. So if you find yourself using it... think again. It could be appropriate, but it seldom is (and, yes, I know sometimes it's appropriate, you don't need to comment to tell me this).

The problem here is one of function-naming. Without already knowing the difference, the names of the functions listFind() and listContains() do not really distinguish themselves. If anything one might guess the difference is one of return type: listFind() returns a numeric index; listContains() a boolean. listContains() really ought to have been called listFindInElement() or something like that. It's too late in the piece to be suggesting a deprecation of listContains() in favour of that though. What do you think?

As an exercise, why not go have a look in your codebase to see if you have any misuse of listContains()? I just spotted a like 32 misuses of it out of a today of 67 in our codebase (which has around 100k lines of code, to put it in context).

--
Adam