Work-at-Home Dad

June 13th, 2009

I ran across “Changing the Language of Fatherhood” on a discussion site. Since the situation in the article is pretty much exactly the situation I’m in, I wrote up a response:

My wife works outside the home and I work from within it, so to save on daycare costs the baby stays with me all day.

To keep from going utterly insane, I often make trips out to nearby coffee shops and try to work there for awhile (assuming the baby stays asleep and/or quiet). Almost every day someone will come over to me (usually an older man or woman) to ogle the cute baby and ask one of the following:

  • Have the afternoon off work today, huh?
  • Daddy baby-sitting this afternoon?
  • Did mommy need a break?
  • Mommy out shopping?

When I tell them that, no, I take care of the baby all day every day because I work from home, they have no way to respond. It’s an utterly foreign concept in their world. Sometimes they simply say, “wow!” and walk off, but every now and then I get the impression that what I said was so alien that they didn’t process it and continue with small talk designed around the notion that what I’m doing that particular afternoon cannot possibly be how it is every day. Mommy is still the primary and daddy is simply mommy’s backup - and boy it sure is nice of me to give my obviously tired and overworked wife some time off!

I’m not really offended by this - more amused, I suppose. It does bother me sometimes that the men’s restrooms almost universally lack baby changing tables. I’ve taken to just using the women’s on occasion so I can change the baby. I look forward to the day when some self-rightous woman gets in my face about it… :) (At small coffee shops, this is easy since they are single-occupancy restrooms - but if I were at some large-scale place with multiple stalls per restroom, I’d be pretty much screwed.)

What bugs me more than the language surrounding this issue is the “unusual” situation of my being the primary daycare provider combined with being a programmer. As it is, very few people “in the public” seem to understand what programming is. Being a work-at-home dad just adds insult to injury, frankly, because the nature of the work is such that distraction and/or stress pretty much destroy the ability to do it well - and having your baby within earshot is a surefire way of becoming distracted and/or stressed out.

The response to the whole “I’m a programmer and a stay-at-home dad” thing is usually along the lines of, “it must be so nice to have a job you can easily do from home - you’re so lucky!” “Easy” isn’t the word I’d be using here - but since there’s no simple way to associate how programming is done with any kind of work that the general public tends to understand, it’s pretty much a lost cause. I’m certain most people go away thinking that I somehow get paid to play with a computer all day, so watching the kid at home must be pretty easy. Ugh.

MenuMaster

June 6th, 2009

I was looking around for a way to launch Hulu Desktop using my Apple Remote instead of it always bringing up Front Row. I couldn’t find a simple, free app to do it - so I made my own. If you’re having this problem, go grab it and thank me later. :)

How I Write Code

May 27th, 2009

My approach is usually to stare out the window or at a wall or blankly at my desktop and “see” the code, in a sense. Almost as if projected onto the world - but not quite. I think I’m seeing packets of meaning rather than programming language text. It’s hard to say for certain. I can move those around and make adjustments and sort of “push” sub-designs to the side, connect them up later, etc. and it all feels very visual. A design will often come to “look” good before I even start typing anything related to it.

Occasionally this doesn’t seem to work. I think it’s when the problem isn’t well defined enough to know quite where to start or if the problem involves doing a lot of stuff I haven’t done before. In those situations I usually have to wait out the process and “watch” code trying to come together in my head until some part of me determines that I simply don’t have enough information to continue. When that happens, I sit down and just start typing code out so that it gets out of my head and into the program. Once enough of that is done, even if it’s crap, that seems to clear up the mental clutter and I can go back to my usual approach and refactor later once I know what that original code was really for or where it goes (if anywhere).

This happens without my wanting it to happen, sometimes. I might be driving and suddenly get a flash of something that’s wrong in the code or a way to fix a bug I noticed hours or days ago. I’ve found memory leaks while driving and nowhere near a computer, for example. It can be a problem when trying to go to sleep at night, too, and I found the best way to deal with it is just get up, fix the code, and go back to bed. Trying to stay in bed and ignore it simply leads to insomnia.

Various Object-Oriented Design Dilemmas

May 23rd, 2009
    [ Concrete or Abstract or Tool ]

A concrete Box object may represent an actual on-screen box where if you adjust the x or y properties of the object, the on-screen box moves and if you remove or delete the Box object, the visible box goes away. An abstract Box object may simply be a container for an x,y,width, and height along with some methods to use to calculate things like overlap, area, or whatever. A Box tool may be an object which only needs to exist long enough to plot some pixels that represent a box on screen (or somewhere else) and then it is no longer needed.

    [ Adding functionality to an existing class/object ]

Some languages allow you to add methods (and maybe member variables) to existing classes without needing access to the original class’ source (Categories in Objective-C, for example). That’s dangerous at times and could yield undefined behavior if you happen to use a method name that was used within the class (but may not have been public) or was also added to the class by another module in your program.

Another option is to subclass the original class and add your new functionality there. This is ultimately more flexible and safer than simply extending an existing class, but there’s a variety of things that make it less than ideal. One big one is that if you’re trying to add functionality to a common library object such as an Array, you now need to re-wrap any arrays you may get as a result of some other methods that only used the standard Array object as a return value in order to use your new functionality. Some languages let you dynamically change the class of an object instance as a way of dealing with this situation. (Smalltalk comes to mind.)

Subclassing has another problem which is that if you’re intending to alter existing behavior and do not have knowledge of the inner workings of the object, chances are good that you cannot add the new functionality without potentially breaking or re-implementing features that the class already has. An example may be a Box object where you wish to add the option of rounding the corners. This box object may also have a variety of other properties already present such as defining line color, fill color, padding, gradients, etc - but the only public drawing-related method that’s visible to you is draw(). Since you can only knowingly override the draw() method, and do not have internal knowledge of the other methods within the class, it is likely that all of the padding, fill, line, etc. effects would need to be re-implemented by your subclass for the case of the rounded corners. Since you don’t know the intricacies of how all of the properties may interact (regardless of what may seem “logical” as viewed from the outside), the odds of doing this properly could be slim. It’s also a waste to have to re-imeplement logic you know is already done for you - if only you knew the name of the functions to call and in which order.

Similar to class extension mentioned at the start of this section, subclassing can also pose a problem when accidently re-defining a method that may have been used internally by the superclass. Without complete knowledge of the object’s internal definition, such a mistake is potentially easy to make. Some languages may offer various levels of protection against this.

If an object is designed for it, delegation can sometimes be used to extend the functionality of an object. Of course in this case you are at the mercy of the design of the original object. If you need to add functionality in a way that doesn’t match what the original author intended and provided hooks for, then you’re in trouble.

If an object is designed for it, it may be possible to extend the functionality of an object by passing in functions or other objects that act as “do-ers” of certain things. For example, the Box object mentioned previously may allow itself to be defined using a different “drawer” object which could possibly allow one to implement rounded corners. This is sort of like a “reverse delegation” in that instead of the object calling out to find additional functionality, it is handed self-contained “engines” of functionality to use later. I don’t believe I’ve ever tried to do things this way, though, as it feels like it’d be pretty clunky and hard to get right in a general way.

And finally, there’s the option of starting fresh with a new object or class and implementing only what you need within the context of your program. In the case of the rounded corners on the Box object, perhaps your program only needs an outline version of a rounded box. While the Box object you originally intended to extend can do fills, gradients, and a bunch of other fun stuff, it’s all things you don’t need right now so it is ultimately easier to make a new object that’s entirely disconnected from Box which only does what’s needed at the time. In my experience, this is what ends up happening most often, and it’s unfortunate, in a way. It seems to be counter to the ideals of object oriented design, but the realities of the process seem to present a significant barrier to “doing it right.”

    [ The black hole ]

After reading through the last section, it may be tempting to sit down and design a small class hierarchy that easily and clearly provides for good ways to share code and solve the example problem of adding a curved corner to a Box object with minimal effort and then shout to me, “Look! You’re wrong! It’s easy if only X, Y, and Z are changed!” Abstractly, it could be done, yes. The point, however, was that the Box object was closed to us. Perhaps it came from the OS vendor and there’s no source to examine or modify. You’re stuck with it as it is.

When faced with the reality that a given object that is not open for internal modification is causing pain, it’s easy to pretend it doesn’t exist and build a whole new object hierarchy that does exactly what’s needed in exactly the way you find the most comfortable and elegant. This might mean simply defining a new RoundedBox object that has nothing at all in common with the given Box object, or it might go so far as to re-define Box as MyBox and re-implement the drawing and features you need and do it in such a way that you can then create MyRoundedBox as a subclass of MyBox and get the job done in only a few lines of code.

Welcome to the black hole of object oriented design. Given enough time, virtually every vendor-provided object you need to extend has some missing functionality, unintended bug, strange performance characteristic, or whatever else that brings your progress to a halt and demands a work around. The workarounds start as hacks, then are re-factored into a “design” and, if you’re not careful, can start to take over your program entirely. Pretty soon you develop a new idiom that the other objects you use don’t obey but you’re convinced is so much better that it’s worth extending more objects, redefining others, and rebuilding the entire puzzle that is your program into a whole new image all in the name of “elegance” or “simplicity” or “extensibility.”

Inevitably, after spending countless hours implementing subtly different versions of functionality that you know already exists buried deep within the system (but which you may not have access to or is officially undocumented, etc) in the name of “design,” a requirement will change and what had only moments before been a perfectly engineered structure capable of withstanding anything becomes a house of cards trying not to collapse in the face of the coming hurricane.

As programmer, you may spend hours upon hours seemingly getting things done. As the project gets larger, “small” changes require ever greater programming effort and “simple” design tweaks ripple through the entire system. From the outside your progress appears to become slower and slower as you sink farther into the black hole - forever not quite arriving.