Hey Swift community!
First things first, this post is my first interaction on here, and I'm still trying to get a feel for things on here, so please excuse me if I butcher this or I don't match the vibe quite right
I'm interested in working on a GSoC project that adds to Swift Stdlib's data structures, mentored by @lorentey! Particularly, a BitArray.
A BitArray works like an Array (in that you're storing a collection of Booleans), except it only takes 1/8 of the memory. This is because each Boolean values takes up a whole byte of memory, when you only need 1 bit to differentiate between true and false values. The BitArray would solve this by bit-stuffing the 1s and 0s to represent the trues and falses respectively into a UInt8, and the implementation behind the BitArray would be more like an Array, where a new element is needed for every 8 Boolean values. The values could be accessed like a normal array, and an example of working code could appear as follows:
`var flags: BitArray = [true, false, true, true, false, true, false, false]
// Accessing and changing values
flags[2] // true
flags[2] = false
flags[2] // false
flags[2].toggle()
flags[2] // true`
flags
could be stored into one UInt8, depending on whether you'd want to store the bits from the front or the back (still need to research which is better), as 10110100 (or decimal number 180) or as 01001011 (decimal number 75). Adding more values would just create a new UInt8, and continue on with the stuffing.
Use Cases
I've serveyed a small number of people on Tech Twitter to see what kinds of use cases such an array could be useful for. I've gotten a wide range of opinions on whether or not this would even be useful, haha. So far I've gotten some neat ideas such as using it for gaming (levels passed), memory usage representation, learning websites (completed modules).
Challenges
The primary challenge I see would be to get the subscript to return a bit value stuffed into a UInt8 as a Boolean. I am hoping this won't be as challenging when I actually get into it as it perhaps appears at the moment. A clever use of bit operations along with some value casting might do the trick, while still permitting an acceptable (maybe even efficient) runtime. I could be wrong, but I'm excited to find out nonetheless.
Another challenge would be to figure out what to do when a UInt8 is holding less than 8 values. This is very likely to be the case with the last UInt8 in the collection. This would be an issue because, say we removed the last 2 values from flag
. Because they would be empty, would we represent those last 2 bits with a 0? Wouldn't that just look like it was 2 false values? This is a challenge that, at the moment, I'm still not sure how to solve, but imagine it would be fun to figure out how to solve it!
Stretch Goals / Exposed Methods
I believe the stretch goals would be to expose new functions to the BitArray. In addition to toggle()
, some obvious functions would be append(val)
, remove(at: index)
, removeLast()
, etc.
These functions along with the data structure implementation will probably take up the entire summer on their own, if not longer. However, it is still neat to think of some other potential functions that could return valuable information to the developer. For example, inspired by a project David Smith (unfortunately can't mention him as I can't mention more than 2 people as a new user ) was telling me about, returning the beginning index of the first block with N contiguous false values could be useful for a BitArray representing blocks of memory where the developer was trying to find a certain amount of free space!
You Mean OptionSet?!
I realized from Bruno Rocha (unfortunately can't mention him as I can't mention more than 2 people as a new user ) that this BitArray is indeed very similar to an OptionSet! I've still yet to do some more research on the nuances between OptionSet and BitArray, but I believe the primary difference here is that OptionSet has a very specific purpose: storing options! I wish I could elaborate more on the differences, but again I still have yet to do more in-depth research!
So no, not quite an OptionSet, but the concepts are very similar!
My Questions to the Community!
First of all, thanks for reading all this! Second, I'd love to know your thoughts on the following:
-
In your development experiences, where and how could you see a BitArray being useful or more optimal in your code? (Looking for some use cases here!)
-
What other challenges do you see that my noob self might not have been aware of?
-
What kind of functions would you like to see such a data structure be exposed to?
-
Any other general thoughts!
All thoughts, opinions, and insights appreciated! Thanks so much!
Last but not least, I'd like to also mention and give a heartfelt thanks to @kylemacomber for encouraging me, motivating me, believing in me, and giving me this idea as something to work on this summer!
As well as David Smith, who brought me in to the Swift Stdlib world, and constantly encourages and motivates me! And lets me talk out a lot of code, haha!