I've caught a hell of a cold. Where's my health insurance card, bitches?
Work was inspiring again today. I am becoming a better programmer,
mostly at the design level. I started out learning the C/C++ bastardization and only recently got an appreciation for what C++ itself allows.
So, what have I been doing at work?
Monday:
I took auto-generated middleware code and made it into a DLL so that the jokers that I'm working with can do auto-discovering subscription communication-- in Ada for crissakes. I picked a good way to do it; wrapped all the C++ business up in conceptually clear classes and then threw a procedural facade on it. If they were to drop Ada tomorrow, they could use the classes I wrote. If they wanted a different DLL interface, they could write it in five minutes.
Then I wrote a class to enumerate all the threads belonging to a process using ToolHelp32. I like hiding the ugly, h32NowDoAThing(ALL_CAPS_PARAMETERS, hThisFlagForAReason | yItIsAMystery)-looking code away and getting something nice, neat, and shiny-- that still works all that black magic.
Today:
I refactored my PipedChildProcess class into ChildProcess and ChildProcessIOAdapter classes and wrote a SuspendableChildProcess class, inheriting from ChildProcess. The refactoring was good; classes should have easily recognized, distinct purposes. The SuspendableChildProcess class uses the thread enumerator to suspend / resume all threads in a process. So far, I've only futzed around with calc.exe--periodically suspending and resuming, watching the window become unresponsive and then seeing all the input which had queued up go in at once. (Aside: when I typed 'class ChildProcessIOAdapter', I stopped and said to myself, "what, am I programming in Java now?" I've done relatively little OOP and feel some of it (especially Java stuff) leads to a bazillion classes with long names that don't actually make things easier to understand. Then I got over my bigotry and went on implementing the right design.)
This is leading up to what I consider to be the only real, technical challenge of what I've been working on: taking a multithreaded program which runs in real time and can only be superficially modified and making it run at an externally dictated, slower than real time pace without *fingerscrossed* affecting its behavior.
Regardless of how this last step turns out, the experience has been a big confidence-builder. I've had some damn good ideas and made them work. I've been discouraged by the tools, the isolation, and the high-level design choices or lack thereof, but despite that my code sure isn't sloppy. It's probably better designed than it would've been working in a modern shop. Nobody's around to check the quality of my code, but I'm sure they'll be able to use it in the future. It's a matter of pride to do it right, so that someone else could pick it up and run with it if they need to.
The last guy they had on rotation with my current group decided that he would just reimplement the algorithms in C++ because he knew it. I can understand the desire, but knowing that software-in-the-loop is the real goal and having slogged through the Ada and the Fortran, I've got to say that just sounds WEAK. It has been rough: being surrounded by people who don't think "you can write fortran in any language" is a joke; working to interface two chunks of code, both written in inflexible languages, one of which I don't even have source for; possessing (for all I can tell) more understanding of what sound software engineering would be than decision-makers; working with a ten-year-old, Frankensteined C++ compiler. It has been real.
I don't think there's much more I could absorb about how to do integration programming. It is by its nature different for every pair of programs and platforms and OSs, but I feel confident that I've learned how to learn that stuff. The question is, do I want to work primarily as an integration programmer? The answer is hell no, not on this busted old shit.
I've felt that I am a weaker designer than implementer for a while; mostly I noticed that whenever I have an idea, I want to jump straight into coding it bottom-up, starting at the stickiest part. It works fine with dirty integration programming, where everything has a rather experimental nature to it.
Unfortunately, this doesn't jive with making good overall designs or object-oriented design. This has been the sticking point in realizing programs that I'd like to write. I have to force myself to step back and figure out what I want to do and I'm no good at that--just like in life outside computer programming!
My current personal project is a memorization manager, basically a flashcard program on steroids. You feed flashcards into it, it tests you on the flashcards, nothing new in that. The (only kinda) novel part is that it will keep track of your testing history and use that to guesstimate what you are most likely to have forgotten and then test you on that. Because I like generalizing, it's designed to allow flashcards with different numbers of fields for, e.g., different languages. I've got flashcard kinds for Japanese->English and Chinese->English and I think that the structure might even be general enough to allow wacky things in those languages with more involved or irregular morphology: easily generate a test on the forms of words regardless of whether they are nouns, adjectives, or verbs; extra fields for irregular forms; conjugations calculated automatically. I might use some of those ideas if/when I start learning a Romance language-- or it may be pure wankery that is just distracting me from designing the useful parts of the program.
It's by no means a sexy program, but it's one that I think I would get a lot of use out of. I can't bring myself to look up lists of vocabulary when I know that I'm going to forget 3/4ths of it within a week. Hopefully this program will significantly reduce the effort of managing the maintenance of vocabulary. Automatic, relevant testing takes most of the effort out of reviewing. The theory is that easier maintenance of vocabulary will make expansion yet easier.