In which I have diverse, barely connected ideas and fail to create a structured narrative that ties them together.
Woopsi includes two of the most ubiquitous container classes, dynamic arrays and linked lists, as part of the main library code. Of these, only the dynamic array is used. Linked lists are in there partly for other peoples’ use, but mainly because I wanted to write a linked list template class to complement the dynamic array.
There’s no reason why the linked list class and its associated iterator class should be shipped as part of the Woopsi library code. It would be better if Woopsi came with a separate directory of optional support classes that could be added into applications as required. The linked list would be one such class, and I could add the SimpleScreen and SimpleWindow back into the distribution too (updated to support everything in the current gadget set).
Coding for Noobs
I didn’t explain the rationale behind removing the Simple classes and it is appropriate to mention it here. A few weeks ago I was pondering on how Woopsi’s target audience had completely changed since I began working on it. The original plan was to create a GUI library that would be used in the same way that a web developer works with HTML. You just work with what you’re given and, should you really feel the urge to create new UI components, you do it all yourself from scratch. You can’t subclass an HTML button.
I set out to make a library that included enough UI components to allow developers to cobble together interfaces quickly and, more importantly, easily. Even beginners should be able to assemble GUIs using a tiny amount of code. This is where the SimpleWindow and SimpleScreen classes came in - they wrapped up child gadget creation in tidy methods and reduced the amount of code needed to get a UI working. They also protected the child gadget arrays from external interference and actively prevented subclassing. Subclass prevention was prevalent in the early Woopsi code.
Over time, Woopsi has become less focused on providing a system for newbies and more focused on being a useful tool for a whole range of programmers. As such, it struck me that coding for beginners is counter-productive. Microsoft don’t dumb down their APIs so that beginners can code for them; they write what they need to and layer simple, optional abstractions on top.
I bring all of this up because I’ve been looking into the other main container class - the map/hashmap/hashtable/etc. I’ve never written one before and, although I use them all of the time, I didn’t have a clue how they worked.
Turns out to be fairly easy. A hashmap is essentially an array. Data is added to the hashmap in key/value pairs. When an attempt is made to add data to the hashmap, the key is turned into a “hash”, or integer representation of that key, and the key and value are inserted into the array at the hash index. To retrieve an item from the hashmap by its key, we can just re-hash the key and return the item from the array at the hashed index.
For example, assume we’re inserting an object into the array with the key “myobject”. We take the hash of “myobject” (assume that the hash function in this case gives us the integer value 34). We then insert the key and value into array element 34. To retrieve the data represented by the key “myobject”, we just take the hash of “myobject” again (gives us 34) and return the data at element 34.
It gets a little more complicated when you try to compensate for potential “hash collisions”, or cases where different keys produce the same hash value, and a lot more complicated when you try to judge the efficiency of your hashing function.
Anyhoo, I have a hashmap and a hashmap iterator class working in VC++. It’s not the most efficient example of a hashmap, but it follows the coding style laid down in the dynamic array and linked list classes and thus fits in with the rest of Woopsi’s code. As soon as I’ve converted it to use the PALib type names (u16 instead of “unsigned short”, for example) I’ll add it to the (proposed) supporting class folder.
Coding for Programmers, Coding in Public
Coding a toolkit for programmers is totally unlike any programming I’ve done before. Ordinarily I don’t mind too much if my object model isn’t completely logical, or if I take shortcuts in order to get things done - the nature of the industries I’ve worked in demand that I produce working code as quickly as possible. As long as the code is commented, structured, follows a consistent style and has descriptive names for everything (such that a junior programmer can maintain it or I can pick it up again in 12 months), I’m generally reasonably happy. Naturally I’d prefer it if I could revisit the code, tidy it up and optimise it, but that’s rarely an option.
Coding for other programmers is entirely different. Every piece of functionality needs to not only work, but it also needs to be designed in such a way that it will make sense to everyone else who wants to use the toolkit. The object model must make sense. As Woopsi is being developed in public (open-source is, I think, the closest programming gets to a performance art) all mistakes are easily scrutinised by anyone who cares to download the source, and all mistakes affect anyone using the toolkit. It could be very easy to get into the situation where I second-guess every decision and development stagnates.
Even little things that don’t seem like major design decisions can turn out to be. One example is the way that the Woopsi hierarchy is responsible for deleting gadgets. John - another Woopsi user - noted that this makes it impossible (or at the very least, inadvisable) to create gadgets on the stack. As soon as the gadget goes out of scope it gets deleted, which will leave the hierarchy with (potentially) a lot of trashed pointers. It seemed like a perfectly reasonable idea at the time, but John pointed out that FLTK leaves responsibility for deletion with the user. FLTK UI components can be created on the stack.
There’s a good quote over at Jeff Atwood’s blog about programming for programmers:
“Reuseable components are three times as hard to build”
Although it is arguably more difficult, coding in public gives huge benefits. This blog currently has 215 posts, but this number is vastly outweighed by the number of comments from users - 555 at the current count. The most surprising thing is the signal-to-noise ratio. There are virtually no useless comments. Okay, so most of the comments are by one guy, but when you’ve got one great programmer contributing to your blog you really don’t care.
If I’d decided to keep Woopsi closed-source until it was done, I’d still be coding for beginners and it wouldn’t be anything like it is today. The SimpleWindow class would still be in there.
There’s also the advantage of getting feedback when things go to plan. Here’s a quote from the DSTalk blog, regarding Woopsi 0.30:
Overall I am very happy with the update! Not only are whole host of bugs fixed and new features available to me but in the process of updating my code was vastly improved and tidied up.
Returning to Academia
Whilst on the subject of university projects, I got an email from my old university at the weekend - I’ve got a place on the MSc. The course appears to be assessed mainly by exam, and I haven’t taken an exam in about 7 years.