Seeking to Understand http://blog.bigzaphod.org Huh? Fri, 20 Nov 2009 21:15:38 +0000 http://wordpress.org/?v=2.3.3 en An App Store Idea http://blog.bigzaphod.org/2009/11/20/an-app-store-idea/ http://blog.bigzaphod.org/2009/11/20/an-app-store-idea/#comments Fri, 20 Nov 2009 21:15:38 +0000 Sean http://blog.bigzaphod.org/2009/11/20/an-app-store-idea/ I have an idea that might help improve the App Store. It won’t address every concern, but I think it’d be a step in the right direction.

I propose that Apple take a two-tier approach to the store so that there’s a distinction between being listed in the App Store vs. just being available for sale (or free distribution) via the App Store’s infrastructure.

An app would need to be approved in the usual (current) manner in order to get indexed, or to have a chance at being featured, or put on TV, or put on demo units at Apple stores, or a chance of being on the top 10 lists, etc. However prior to approval (and after rejection from being listed) any submitted application that passes the static analysis tools and any automated testing processes (does the app work?, does it use any undocumented calls?, etc), would get a URL that links to the app in iTunes or the App Store app where it can be purchased directly. There could be a note along side of it that the app wasn’t approved or vetted by Apple, the buyer is at risk, it’s not stocked on the App Store’s virtual shelves, etc. - but it’d still be available for sale (albeit indirectly) and subject to the marketing of the developer themselves with no implication that Apple condones it (yet).

This would remove a significant amount of the risk of developing for the iPhone because unless you’re trying to hack the system or use undocumented or forbidden code, you’d still at least be able to offer it up for sale by yourself while taking advantage of the underlying distribution and payment system Apple has created. (And Apple still gets their 30% cut.) Plus, Apple (and the rest of us) would have a chance to see if the apps they’ve been rejecting really do include the gems we want to believe are there.

]]>
http://blog.bigzaphod.org/2009/11/20/an-app-store-idea/feed/
Trying Objective-C Blocks http://blog.bigzaphod.org/2009/09/22/trying-objective-c-blocks/ http://blog.bigzaphod.org/2009/09/22/trying-objective-c-blocks/#comments Tue, 22 Sep 2009 20:06:59 +0000 Sean http://blog.bigzaphod.org/2009/09/22/trying-objective-c-blocks/ Today I was experimenting with Objective-C’s blocks so I thought I’d be clever and add to NSArray a few functional-style collection methods that I’ve seen in other languages:

@interface NSArray (FunWithBlocks)
- (NSArray *)collect:(id (^)(id obj))block;
- (NSArray *)select:(BOOL (^)(id obj))block;
- (NSArray *)flattenedArray;
@end

The collect: method takes a block which is called for each item in the array and expected to return the results of some operation using that item. The result is the collection of all of those results. (If the block returns nil, nothing is added to the result set.)

The select: method will return a new array with only the items from the original that, when passed as an argument to the block, the block returned YES.

And finally, the flattenedArray method iterates over the array’s items. If an item is an array, it recursively calls flattenedArray on it and adds the results to the result set. If the item isn’t an array, it adds the item to the result set. The result set is returned when everything is finished.

So now that I had some infrastructure, I needed a test case. I decided to find all package files in the system’s application directories. This is what I came up with:

NSArray *packagePaths = [[[NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSAllDomainsMask, YES) collect:^(id path) { return (id)[[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil] collect:^(id file) { return (id)[path stringByAppendingPathComponent:file]; }]; }] flattenedArray] select:^(id fullPath) { return [[NSWorkspace sharedWorkspace] isFilePackageAtPath:fullPath]; }];

Yep - that’s all one line and it’s horrid. I tried a few approaches at adding newlines and indentation to try to clean it up, but it still feels like the actual algorithm is lost in all the noise. I don’t know if it’s just a syntax thing or my relative in-experience with using a functional style that’s the problem, though.

For comparison, I decided to do it “the old fashioned way” and just use loops:

NSMutableArray *packagePaths = [NSMutableArray new];
for (NSString *searchPath in NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSAllDomainsMask, YES)) {
	for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:searchPath error:nil]) {
		NSString *packagePath = [searchPath stringByAppendingPathComponent:file];
		if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:packagePath]) {
			[packagePaths addObject:packagePath];
		}
	}
}

IMO this version was easier to write and is more readable to boot.

I suppose it’s possible this was somehow a bad example, but it seems like a legitimate way to use blocks to me. (Am I wrong?) Am I missing something about how to write or structure Objective-C code with blocks that would clean this up and make it clearer than (or even just as clear as) the looped version?

(Also posted this on StackOverflow since my blog is not exactly popular.)

]]>
http://blog.bigzaphod.org/2009/09/22/trying-objective-c-blocks/feed/
Phil Schiller Needs To Watch His Back http://blog.bigzaphod.org/2009/09/09/phil-schiller-needs-to-watch-his-back/ http://blog.bigzaphod.org/2009/09/09/phil-schiller-needs-to-watch-his-back/#comments Thu, 10 Sep 2009 01:08:49 +0000 Sean http://blog.bigzaphod.org/2009/09/09/phil-schiller-needs-to-watch-his-back/ I’m right behind him! My bee is just barely sneaking a peek - it’s nervous about being on such a huge stage. :D

twitterrific999.jpg

]]>
http://blog.bigzaphod.org/2009/09/09/phil-schiller-needs-to-watch-his-back/feed/
Ramp Champ Is Here http://blog.bigzaphod.org/2009/08/24/ramp-champ-is-here/ http://blog.bigzaphod.org/2009/08/24/ramp-champ-is-here/#comments Tue, 25 Aug 2009 03:57:33 +0000 Sean http://blog.bigzaphod.org/2009/08/24/ramp-champ-is-here/ The largest iPhone game I’ve worked on, Ramp Champ, is live! Go buy it in the iTunes store! :)

]]>
http://blog.bigzaphod.org/2009/08/24/ramp-champ-is-here/feed/
Tiny Violin http://blog.bigzaphod.org/2009/07/27/tiny-violin/ http://blog.bigzaphod.org/2009/07/27/tiny-violin/#comments Mon, 27 Jul 2009 20:40:04 +0000 Sean http://blog.bigzaphod.org/2009/07/27/tiny-violin/ There’s a huge number of things on my mind and I don’t know what to talk about or even if I want to talk about any of them. I have to do something, though, because I feel like I’m being blocked by them. I used to blog a ton about things - especially personal stuff - and it always felt a bit like relief to get the images out of my head. I figured I might as well try again, since it’s been forever.

Probably the most stressful thing in my life right now is the presence of Amos. That’s not to say he isn’t awesome - he totally is - but there’s no point in pretending it isn’t hard to be a parent sometimes. He’s a baby. He doesn’t really cause any of the stress himself directly like a dramatic teenager might. He’s just trying to exist and learn and live and has wants and needs he doesn’t always understand. (The sad thing is, I think sometimes that describes me, too, and I’m almost 30x his age right now.) The real cause of the stress is my own mind.

I work from home and there’s no daycare or babysitter. He’s here with me all day, every day. Our family is somewhat opposite of “normal” in that dad is the primary caregiver. As I’ve blogged about in the past, I’m occasionally met with social-induced grief/comedy - but that’s minor stuff. The problem is what this situation does to my overall state of mind day after day.

Lately I’ve felt utterly mentally spent. This has happened before, of course. I seem to run in cycles. The thing is, the usual reset patterns of being alone for one or two days, hiding from the world in code or a game, hiding in public at a coffee shop, etc. just don’t work very well. I haven’t been able to do them with any real success since he was born and, honestly, some of them have been harder or impossible since getting married.

I can’t seem to find any reliable way to reset anymore. Melody works insanely long hours, comes home, is understandably tired, and so sometimes it feels like I have to take care of her, now, too. Of course the thing is, I’m also tired after a day of being mentally strained by the simple presence of Amos and his incredible potential for distraction. It’s no wonder that sometimes I get a little angry inside when I have to do more Amos care-giving after she does finally get home from work or has a day off. It feels like it’s always all on me to make sure everyone stays sane or happy.

I suspect that stay-at-home moms feel this way too - but they at least can commiserate with other mothers and feel better afterward. Guys don’t have that, really, but an additional issue is that we’re just plain made differently. Sitting around and talking about it doesn’t really help unless the discussion revolves around fixing the problem. In fact I think just talking about it idly can make it worse. It just serves as a reminder of the ever-looming situation that is seemingly unsolvable which leads to a feeling of everlasting hopeless despair.

My work is entirely intellectual. It requires focus and thought. It requires failure, frustration, and discovery. Overall, though, it requires some degree of predictability. The phone must not ring at the wrong times. The dogs must not bark at the wrong times. Amos must not suddenly wake up screaming after pooping all over his playpen at the wrong times. The only certainty I have anymore is that these things will all happen precisely when they are the most difficult to deal with. I still maintain that the only people who understand this are other programmers. There’s apparently no parallel in general that non-programmers ever seem to be able to relate to because non-programmers have such warped ideas as to how our job works.

While engaging in the act of programming, I may wander around the house, stare off into space for an hour, clutch my head in my hands while slamming it against my desk, “listen” to a general tech podcast like TWiT while doing nothing else, or read marginally-related documentation or academic white papers, and sometimes I type funny looking text into an editor. People who don’t understand programming see this kind of thing and assume I must have the easiest job on earth and the fact that I’m whining about having to be home with my baby all day while working this cherry gig is further proof that I don’t know what the hell I’m talking about and that I’ve failed at life. After all, a lot of guys love coming home from work so they can spend a few hours a day with their kids and here I am bitching about spending ALL of my hours with my kid. “Must be nice!”

I think the best example I can come up with for what it’s like to be a programmer who’s also taking care of his infant child is this: Imagine you’re an auto mechanic. Not all jobs on a car require putting it up on a lift, but a lot of them do. Now imagine that your kid was always nearby in his playpen and whenever he cried, which is at least 8 times semi-randomly throughout the day, you had to stop what you were doing, clean up your hands, and go feed him or cuddle or change a diaper for a little bit, etc. Not just too bad, right? Well now imagine that whenever he cried your lift would always fall down. It doesn’t take long to realize that when you have to work under the lifted car, you’re going to be just a little bit paranoid…

So the obvious solution to some of this is to just get a babysitter/daycare and end this work-from-home-daddying experiment. Unfortunately, this is easier said than done in light of the second most stressful thing in my life right now: no money.

Around 11 months ago I joined a new company with a lot of promise and big ideas making iPhone apps for themselves and others. The first project I did involved a whole bunch of domain knowledge I didn’t have, a few changing requirements, and some technical complexity. Naturally it went over budget and took longer than it should have. Well, shit happens, right? My next project was a game which, once again, required a lot of knowledge I didn’t have up front, changing requirements, and technical complexity. Guess what happened? Yeah, it went over budget and over time, too. Shocking, I know, although it was horribly fun and awesome. :)

This is all pretty standard business from where I’m sitting. I’ve never been on a big project that didn’t go too long or cost more than expected. The thing is, the company wasn’t really in a position to be able to absorb that kind of risk with the game. I worked for 4+ months on a huge project that wasn’t making any income during that time and, while I don’t really know for sure, I get the impression they thought it’d take maybe 2 months originally. That’s even worse than going over budget with a client who at least paid for the initial time (and, if lucky, was billed for and paid the overages, too). The result here is that the company started to run out of money and getting paid became somewhat of a game of chance. Since Melody and I have no debt (except the house), have a large emergency fund, and were even budgeting a month ahead of realtime, aside from being slightly annoying, it didn’t really matter much if payments were late. I kept working.

The issue is that eventually payments weren’t just late - they were missing. The company had slowly become very far behind. 6 weeks, actually. Our month-ahead budgeting system was no longer enough padding to contain the delays, which meant that it was about time to start digging into the actual emergency fund just to get minimum bills paid. (We had even cut way back on some stuff for the sake of saving money before any of this became a major issue. For instance, we no longer have any subscription television and use Hulu for almost all visual entertainment thus saving a lot of money per month.) We both felt the situation had become unacceptable. The emergency fund is for unforeseen things like a car accident or an exploding washing machine or something like that. It’s not for buffering the fact that my employer isn’t paying as promised. The solution there is to get a new employer.

(Side note: Avoid drama by making sure you never have an employment contract that includes an overly general non-compete clause. Avoid them entirely, actually. After some discussion, the company agreed to nullify mine but it made the process more difficult than it needed to be.)

I really didn’t want to stop working on the game - it was very nearly done and totally awesome. There were just a few small things yet to wrap up, but I had to end it so that I could move on before we really got into a bad financial situation. So I stopped. Almost at the same time, The Iconfactory decided they wanted to hire a new dev of their own. I immediately applied, and starting on Wednesday I will begin working with them on a new project. So that’s totally cool and should be an awesome thing.

The downside of this situation, though, is that being 6 weeks behind has caused a serious shortage in our budgets, and next month isn’t yet complete - as in, we don’t have enough cash yet to cover the minimum expenses of our insanely boring and relatively cheap lifestyle. (Hell, we only have ONE car, no “normal” TV service, no landline phones, no subscriptions of any kind except for the cellphones, a small/cheap house, etc! I mean geez… how much more simple can we get, anyway?)

The old company still owes the back pay, of course, and I think I’ll get it all eventually - but they have until August 31 to settle up. I didn’t want to get all bitchy and demand it immediately - which by rights I probably could have - because that’d basically have killed them. They are good guys - it’s not like they had the money to give or else they’d have been paying everyone all along. :) This gives them a few more weeks to finish some more client work, get some checks in from laggards, pay the people who haven’t left yet, and at least hopefully get the game in the store. Still, though, that leaves me with an additional one month gap after coming out of a 1.5 month shortage as it was! It’s going to be very rough.

I hate how money can dominate the mind, but it does. Checking the bank account each day, reconciling bills, etc. all serve as reminders of how short everything is and how close to the edge it feels like we’re at. The truth, of course, is that there’s enough money in the bank to probably survive until Christmas with a decent lifestyle if we really, seriously, had no other choice - but that’s not the point. What if we were living off that and then a real emergency happened? We’d be screwed. “Oh, that’s what credit is for!” Oh great… so I can have credit so that a terrible situation that we could have paid for with cash had we not used the emergency fund money is transformed into debt payments for the next 2 years or something? No thanks!

So anyway, those are the big two stresses in my life in a large scale sense. There’s a third - which is my apparent inability to focus on doing things that I seemingly want to do, but then don’t do and instead sit around and lament the fact that I’m not doing them. It’s hard to describe and I don’t have a solid line of thinking about it yet. Sometimes I blame the baby always being around for my not being able to concentrate - and I think that’s a really huge part of it sometimes - but I don’t believe it is the whole story because this happened before I even moved out of my parent’s house. It seems there’s a greater force at work here which prevents action even when I apparently want to take some action.

An example is that lately I sometimes have ideas about artificial life simulations. Mostly they involve a dot moving around and, seemingly, just doing random crap (because my ideas rarely seem to actually work correctly). I get almost haunted by what I think should work in a large scale: the idea of trying to have intelligent behavior emerge from a set of simple rules. The thing is that it’s a hard problem and my success to date has been very poor because, perhaps, I don’t really understand *exactly* what I’m trying to achieve at any given time.

I have grand visions for these ideas where a huge 3D world could exist and a player could play in it while interacting with or at least observing the bots in the game acting as if they are real and doing real things. My classic idea is having a little town in this “game” and the town is scared of the nearby wolf population. A player could come along and cull the pack of wolves and thus the threat of the wolves drops and the town is happy and loves this player. A huge complex living system could exist where the players help the NPCs do things or deal with problems or whatever as they live a sort of “real” life in this virtual world that was never pre-scripted. The key is that the wolf pack may have started life somewhere else and found their way to this village because of a good food supply or something - acting entirely in their own self-interest. The villagers also act in their own interest and the human player is there mostly as an adventurer helping the “boring” people of this world survive in some way. Something like that. It *feels* possible. But that’s about all I’ve got at this point - feelings.

I often think about ways to make something like that work. I always dream for a few weeks of free time where I could play with those ideas exclusively. The issue is that when I get that time, I squander it. I’ve been tormented the last couple weeks (that I’ve been effectively unemployed) by these ideas - only I did very little with them. And now time is running out. I only have one more day of “vacation” left and I’ve done nothing of significance. It’s like I’m too afraid to really work on it. Every time I do, I tend to fail pretty massively. Perhaps I’m trying to avoid failure? Perhaps the problem is still too hard? Perhaps I don’t have a decent mental framework for it? Or perhaps I’m afraid it’d actually work one of these days and I’d then have to leave it for the “real job?”

I just don’t know. What I do know, though, is that it drives me crazy. It isn’t just this AI stuff, either, but other ideas I might want to do. Sometimes there’s the “no money” excuse. Other times there’s the “but I have a kid now” excuse. Or otherwise it’s “I have a wife and she’d have to agree to this crazy idea” excuse. Etc. Lots and lots of excuses. If I could sell them, I’d be rich and have a babysitter - ironically, I’d then lose a huge source of the original excuses. Life is funny that way.

]]>
http://blog.bigzaphod.org/2009/07/27/tiny-violin/feed/
Work-at-Home Dad http://blog.bigzaphod.org/2009/06/13/work-at-home-dad/ http://blog.bigzaphod.org/2009/06/13/work-at-home-dad/#comments Sat, 13 Jun 2009 20:11:32 +0000 Sean http://blog.bigzaphod.org/2009/06/13/work-at-home-dad/ 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.

]]>
http://blog.bigzaphod.org/2009/06/13/work-at-home-dad/feed/
MenuMaster http://blog.bigzaphod.org/2009/06/06/menumaster/ http://blog.bigzaphod.org/2009/06/06/menumaster/#comments Sat, 06 Jun 2009 17:42:54 +0000 Sean http://blog.bigzaphod.org/2009/06/06/menumaster/ 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. :)

]]>
http://blog.bigzaphod.org/2009/06/06/menumaster/feed/
How I Write Code http://blog.bigzaphod.org/2009/05/27/how-i-write-code/ http://blog.bigzaphod.org/2009/05/27/how-i-write-code/#comments Thu, 28 May 2009 01:16:19 +0000 Sean http://blog.bigzaphod.org/2009/05/27/how-i-write-code/ 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.

]]>
http://blog.bigzaphod.org/2009/05/27/how-i-write-code/feed/
Various Object-Oriented Design Dilemmas http://blog.bigzaphod.org/2009/05/23/various-object-oriented-design-dilemmas/ http://blog.bigzaphod.org/2009/05/23/various-object-oriented-design-dilemmas/#comments Sat, 23 May 2009 15:48:45 +0000 Sean http://blog.bigzaphod.org/2009/05/23/various-object-oriented-design-dilemmas/ [ 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.

]]>
http://blog.bigzaphod.org/2009/05/23/various-object-oriented-design-dilemmas/feed/
Fun With LLVM & Whirl http://blog.bigzaphod.org/2009/05/12/whirl-and-llvm/ http://blog.bigzaphod.org/2009/05/12/whirl-and-llvm/#comments Tue, 12 May 2009 22:46:47 +0000 Sean http://blog.bigzaphod.org/2009/05/12/whirl-and-llvm/ It’s been a long time since I wrote any code purely for fun - but I recently finished just such a project.

Pretty much ever since I heard about LLVM I’ve wanted to do something with it. The obvious choice was to build a compiler for one of my esoteric languages. Well, I finally got around to trying it out with Whirl - and it’s pretty sweet.

Since Whirl is actually quite dynamic, the generated code ended up being pretty much nothing more than an assembly language version of a Whirl interpreter with the given Whirl program packaged in. Oh well.

This entire project is pretty useless, frankly, but that wasn’t the point. The real point is that, with a few jumps through some hoops, I can actually compile Whirl code into a native executable. How’s that for bad ass?

Compiling the compiler is pretty easy (must have LLVM and gcc installed, of course):


g++ -O3 whirl-llvm.cpp `llvm-config --cxxflags --ldflags --libs core jit native` -o whirl

This yields an executable which will take a whirl source file and not only print the LLVM instructions to stderr, but also JIT the resulting compiled Whirl program and run it. Any results are printed to stdout. This is pretty neat by itself, of course, but the real magic comes with a few more commands:


$ ./whirl slarty-hello_world.txt 2> hello.llvm
$ llvm-as -o hello.bc hello.llvm
$ gcc -o runtime.o -c whirl-runtime.c
$ llvm-ld -native -o hello hello.bc runtime.o

After this series of commands, there’s a platform-native executable named “hello” in the directory! You can run it just like any other native binary. Freaking awesome!

The LLVM crew is working on native code generation out of the box. Right now it requires gcc (and llvm-ld cheats and calls out to gcc internally) to actually construct the native executable. (Well, technically it just needs “as” and “ld”, but my toy here relies on a couple C functions since that was an easy solution. I suppose I could have compiled it with llvm-gcc, though.) Eventually, perhaps after this year’s Google Summer of Code, there will be an all-LLVM solution which would lead to a completely standalone compiler. I’m looking forward to that!

So anyway, you can grab this (likely terrible) code for my LLVM Whirl Compiler right here. Don’t forget to grab the “runtime” code, too, which cheats a bit and uses some C functions to do the Whirl I/O commands.

]]>
http://blog.bigzaphod.org/2009/05/12/whirl-and-llvm/feed/