The following assumes C# as a reference language, or any other statically typed language. This is not a question specific to Unity's API, but it is used as an example.
In Unity's API, most people come across the Raycast function. This has an argument, of type
layerMask. This is an integer, that works as a bitwise mask (if there's 1 at the n-th place, the n-th place is included in the calculation).
I always thought that this was a very weird design choice for their API.
First of all, I should clarify, that there can only be 32 layers in Unity, thus, those layers are finite, but you can have any number of layers (below 32).
Personally, I would ask as an argument, an array of integers, whose elements would be the layers that you wish to raycast against (identical to the actual implementation, just without it being bitwise). Another way, would be to have variardic arguments, if the language supports it. (these points also apply to dynamically typed languages). (I have read a few arguments against the use of variardic arguments, so I wouldn't choose this one)
The actual question
Why would one choose a bitwise mask as a representation of a selection of a (finite/bound) amount of items, instead of an array of the selected items?
Given that you are sacrificing usability and readability*, what are the benefits?
Since Raycast is a very useful function and used widely, I'm guessing that they chose this for performance reasons (bitwise operations can be much faster than iterating over an array). In this particular case, given that the maximum length of the array would be 32, I doubt that the difference would be huge, but I'm guessing that every bit of performance counts in this case.
The other benefit is certainly memory footprint (one integer vs a whole array of them), but I doubt that this is generally important (in this and other cases).
I'll also notice, that both arrays and integers, do not enforce the size boundary of the items. The array, can be as large as you want, and the integer has a certain, implementation/machine specific size, so if you wanted to toggle 17 items, no size of integer would be enforcing that there is no element 18.
*Example: To signify the third and fourth items, instead of the argument
12 (1100 in binary), you could have