Deep in my transgressions,
buried in the sins I cling to.
How long, O Lord, how long,
before You strike me down?
My sins stand before me, accusers and witnesses,
a testament to my faithlessness. They mock me,
saying, "Here is one of great worth,
for he diligently makes evil from good, all the day long,
and he makes war against God without ceasing."
Your courts are for the holy,
those without fault,
those who have no blemish.
For me, there is fire, death, and torture:
the gates of hell stand open to receive my soul.
Judge and Arbiter of the nations,
in whose hands are justice and wrath,
who can be found that is holy?
Who is righteous?
Who is without fault,
and where is the man who has no blemish?
Your mercy is infinite, without measure;
like the spring running down the mountain,
it never ends, never ceases to flow.
In its shimmering depths, my sins are drowned,
And I am set on the heights, to stand before You.
May I give thanks to You,
and remember Your love and kindness forever.
Ever since Homer (and probably before him, too), storytellers and bestowers of wisdom have felt the need to make their audiences sit through the setting of the stage before they get the goods.
This ancient bedrock upon which all good stories are built might be summarized for the modern era thusly:
"There can be no decapitations unless there are first characterizations."
(Hmmm. I seem to have defined most of American filmmaking out of the realm of storytelling.
And you know what?
I'm okay with that.)
How did codeninjaz.net, inc, first come to be?
"In the beginning, God created the heavens and the..."
Okay, fine. Most people don't want as much context as I usually do, so I'll start a little closer to the end.
Several years ago, I graduated from Penn State Harrisburg with a degree in computer science.
In my two years there (the first two years of my degree were done at HACC), I befriended a few individuals, as even computer scientists are wont to do.
My crowd, although it varied a bit, had at the core Bob Stouffer, Andy Jones, Nate DeStefano, and myself.
We spent quite a few hours slaving over homework together, hacking on projects late into the night, playing video games (on one memorable occasion, playing a celebratory round of Marathon 2 in networking class, after receiving a 97 on our final presentation), and finding hilarious things on the Internet while Bob slaved on some massive project or other.
Once, Bob, Andy and I decided to participate in the ACM's annual student programming contest.
It was more for fun than anything, and we weren't expecting to do particularly well (though we may have been expecting to do a little better than we actually did). We had two practices, while many of the schools that participate had full semester-long classes dedicated to contest prep.
In a nod to our anticipated level of performance, we selected our team name carefully:
As I hinted earlier, this proved to be a very insightful team name.
Still, we enjoyed ourselves, got to eat lots of free junk food, and learned a lot about how not to win programming contests.
Eventually, it inspired my purchase of the codeninjaz.net domain.
Several years later, when Bob and I decided to try a startup, it was too perfect a fit to resist - codeninjaz.net, inc was born.
So much for characterization, minimal as it was. From here on, expect decapitations.
From September of 2007 through May of 2009, a friend and I attempted a startup project together.
We ended it, and released the unfinished (and rather sloppy) source code several months ago, so people could dig through the pile and find any useful parts they might wish to scavenge.
(Aforementioned startup is most of why this site has had so few updates since the fall of 2007. I'm thinking about requiring myself to get at least one post a week up, because I've been shamefully neglectful of writing in recent years.)
It's tempting to call it a failure - the two of us slaved for more than a year and a half on the project, only to give up without launching and without making any money. At several points during the project, I was frustrated, angry, and wondering what on earth I was wasting my life on this for.
And yet, I cannot call it a failure, despite the temptation to do so.
Through doing it, I learned quite a few important lessons about the art of making software, lessons that would not have been easily learned any other way.
I also learned some very important things about myself, some of which I might not have realized for years had I not been neck-deep in writing software for eighteen months.
These are ancillary, though - the real reason I cannot call it a failure is that I was trying to follow God.
Before we had even begun the project, I said to several people (one of them my partner), "The idea makes little sense to me - I don't think the proposed product is a marketable one, but after praying extensively, asking family and friends for advice, and thinking it over, I do believe this is something God is leading me to do."
Looking back, I think I can see some of why I was supposed to work on the project, and what I was meant to learn from it.
This, then, will be the topic for a few weeks - the lessons learned in the rise and fall of codeninjaz.net, inc.
It might be informative to imagine that this event tap is interested in both keyboard events, and mouse button events.
Let us further suppose that the software which you're working on causes an uncaught exception of some variety.
If, hypothetically speaking, XCode was configured to automatically drop into the debugger on errors, this uncaught exception would invoke the debugger.
We might extend the conjecture yet more, and propose that when the debugger took control of your software, the aforementioned event taps were active.
Should all of that be the case, a remarkable thing would result.
Control having been seized by the debugger, the program thread handling the incoming events from the event tap would no longer be capable of processing incoming events, paused as it would be.
With no event being returned by your software's event tap thread, OS X would, one imagines, quickly queue up a number of input events.
Since, however, these would not be processed (according to our theoretical model), OS X would do its duty, and display the spinning wait cursor, often referred to by names not nearly so pleasant.
The cursor, one judges, would still respond to mouse movement events - after all, in the outlined situation, mouse movement events were not of interest to the aforementioned event tap.
Most application UIs would continue to update. Cursors would blink, the system clock would continue to count up, and one might even see a friend sign on, if Adium's contact list was positioned in a visible location.
Yet, for all this visible activity, your machine would be effectively dead in the water, no more usable than if it were frozen, with the kernel panic message writ large over your screen, because, with your event taps still active, but frozen by the debugger, the system would be incapable of processing any mouse click or keystroke.
In further exploration of the possible, visualize yourself banging your head against the desk repeatedly, thinking of all the state that is still humming happily away, but is utterly and unrecoverably beyond your reach.
In the unactualized universe where you find yourself, reflect on how intensely ironic it is that this should happen in the process of writing code to let software state survive exactly this sort of freeze.
In a final moment of imaginative exercise, sigh, and with a saddened flick of the wrists, reboot your machine.
Isn't imagination wonderful?
Some time ago, I was using Gimp to knock out a quick, ugly prototype of a UI.
Having been raised on Photoshop, I didn't know Gimp's toolset very well, so while trying to figure out how to change font size in the text tool, I clicked 'Help'.
Without warning, Gimp lost focus, and I found myself staring at a Safari window, displaying a page I didn't recognize.
It took me about half a second to realize that Gimp had popped open a help page in my browser.
It was disorienting, and if I hadn't already had Safari open, it would probably have been more confusing - imagine clicking help, getting no response, and then after a few seconds, suddenly having an application switch take place.
This is bad UI.
If the user takes an action that's going to change his working state in a significant way, there should be some visual transition that makes it obvious what's happening, or at least that something is happening.
In this case, Gimp caused an application switch. Instead of doing it rapidly without notification, it should probably have gone a bit more slowly, and displayed the standard OS X Command-Tab UI, so that the transition being made was obvious.
(This assumes you think Gimp should have been allowed to change state on me like that at all, which I do not necessarily approve of.)
I'm not asking for a proliferation of dialog boxes - quite the opposite. Surprising the user is bad because he loses track of what he was doing (there are probably other reasons, too). Unnecessary dialog boxes can also have this effect.
Nate Matias did a great job with this in his implementation of the Tinderbox Stretchtext Writing System. When you expand/contract the stretch part of the text, there's a nice fade-in/fade out effect that makes it easy to tell exactly what part of the text body changed.
When you do major state transitions in a GUI, give visual cues.