Tuesday, June 30, 2009

Dry Season

It seems that I've hit a dry spell again. The inspiration of working on LightFrame is virtually zilch.

It probably has something to do with the fact that I've done it as far as to call it a working proof of concept ("I was able to do it"), and have done everything a product usually needs, except bundling it into a neat package. Oh, the users and/or audience were noticeably absent too. So, I'll let this be a while again. This time, it might be for good. Or, not. I don't know.

In case this becomes my last sign-in, I'll just say that I don't regret a single line of code. I would, actually, recommend doing something like this to anyone, if only for the learning part. This has made me so much more a good programmer, than any amount of small projects I could have dreamt up. It has been a nice challenge, and, in the grand scheme of things, I've loved every moment of it. In case this isn't my last post. Well. I'm happy.

But, for now, näkemiin.

Saturday, May 16, 2009

Documentation is Complete

The first round of documentation is considered complete, done, closed and gotten over with.

It doesn't mean that the documentation would be in its final form – it's not. It doesn't even mean that it would be a well written documentation – it most definitely isn't. But it's the start, a start, which is much easier to extend and build upon, than reflecting incremental changes in the code to the documentation.

I'll take another breather from LightFrame after this milestone and probably won't touch it for a while. But, once I get the urge to touch it again (probably within the next week-or-so), I'll be cleaning up the code, so that it's less embarrassing. But no new functionality per se is planned in the milestone. That comes in the milestone after the next one...

A sample deployment on the documentation can be found at my test server. Ignore the sample layout, it's the text that's the actual documentation.

Thursday, March 26, 2009

A Lot of Evil

Since LightFrame is still in documentation stage, which advances at an excruciatingly slow pace, here's another one of my random CS-related ramblings.

Pre-ramble


I have a post in my drafts that I started writing on which has some frequently used phrases to keep bad code to a minimum. I guess you've heard at least some of them: DRY (don't repeat yourself; write one routine instead), YAGNI (you ain't gonna need it; write the feature only once you need it) and the like. One phrase I have been been thinking especially much lately about is "premature optimization is the root of all evil," and this will be the topic of this blog post. This just might evolve into a series. It's not like I'll make any huge advances in the documentation any time soon anyhow...

I first heard the phrase in question quite recently, actually – couldn't be more than a few months ago – at my current workplace. In hindsight, I'm pretty amazed that I've managed to miss it for such a long time, because now that I heard it, I'm starting to see it being used everywhere. It's not like it'd be new a phrase, either; according to Wikipedia, it was popularized in 1974 by Donald Knuth. The way I understand the point in the phrase is that if you optimize the wrong thing or the wrong way, you might be just wasting your time, because it never would've became an issue in the first place. Maybe even worse; what would've perhaps been faster in the average case, actually performs slower than it would unoptimized, because the cases your code runs are not the "average" ones.

I'm not opposing the message of this phrase, but this post would be superfluous if I'd let it rest at that and let it be at that. No, I do have my objections relating to how it's being used. Encouraged by the unexpected corroboration in the Stack Oveflow podcast #47, I decided to write a whole blog post about just this one topic.

Root Cause


My problem with the common usage of the phrase "premature optimization is the root of all evil" is that it's too easy to be misused and misunderstood. It's too easy to hear "just friggin' code it! If it's slow, we'll fix it later." It's all too easy to understand it suggesting to code what's written fastest at first, and if it doesn't work, track back, and do it properly later. This is is a very dangerous interpretation, that might destroy the project's future. There are at least three dirty things that pop right out.

There Will Be No Spoon


Starting with the easiest, yet hardest truth: There's no "later". Face it—That tweak time that you have scheduled at the end of the project? It won't happen. A very cruel, yet realistic in my view, thought on the matter is Hofstader's Law: "It always takes longer than you expect, even when you take into account Hofstadter's Law."

I mean, really, how many projects with a deadline have you worked on, where the project was done before the deadline, with a decent margin, so that you just spent the rest of the days playing Rock Band? I guess not that many. The allured tweak time will be consumed by fixing those contract-busting bugs, or the last-minute features that "simply need to be done".

There's no time like the present.

The Spoon Currently isn't


Not entirely unrelated, the next noticeable red flag is the sound of overall hurry and a distinct chaos that comes with it. This smells like a poorly planned project. So many projects think of bugs as unexpected faults in the program. While bugs certainly are faults, and the individual bug might be unexpected in its respective location, it should never come as a surprise that code has bugs. So why not take them into account, when planning the schedule?

I've recently fallen in love with Scrum. Without going through the particulars, it's a divide and conquer method of planning projects with rapid iterations. In other words, some of the main points are breaking larger problems into smaller and smaller pieces. These small pieces are then dealt with in periods of a few weeks. At the end of each period you have something that is fully functional (as in, you can play around with it), and, little by little, you build new working stuff on top of old working stuff.

One of the strengths with Scrum is that it keeps the client involved in the projects and informed of the state thereof. If a serious bug surfaces at some point in time, the customer gets to know about it in a way or another. Severities are explained, priorities are shuffled, "mustnesses" of features are re-evaluated.

Time is made, not found.

Just Forget the Damn Spoon!


The most prominent feature in that interpretation, to me, is related to the previous note: The general rushing, and a feeling that the speed of cranking code must be maintained. The feel that there's no time to think, because the code needs to be typed ASAP, preferably yesterday. So we plan to do the major features first. Not to perfection, mind you! Just finished enough so that they work in our project. After all, once this feature is done, we need to continue on the whizbang. Because that blocks the wheybow, which in turn is required by the boola. And we can't ship without the boola, can we?

If you've ever heard the phrase "penny wise and pound foolish", this is a pretty good definition of it. You are so fixed in the short run, that you get tunnel vision and can't see the bigger picture. You think you can't afford wasting time thinking ahead, because thoughts don't have fingers to type code with. This is the numero uno reason why unit tests and technical documentation are rarely done at all – you can't sell tests or specs to your customer, so why bother in the first place?

If you hate the code you're looking at at the moment, someone, somewhere, has been awesomely penny wise. It just better not be you.

Literally


Thus far I have criticized one of the many ways the original phrase could be interpreted. If you think that there's no way to interpret that phrase in such a horrible manner, I salute you. You make me all warm inside, and I wish the best of luck in your life. The rest of you, especially those who didn't see any wrong with the interpretation above, please read onwards.

For illustrative purposes, let me write the quote once more:
Premature optimization is the root of all evil.
Ladies and gentlemen, the key word within the phrase is "premature"! It can't be emphasized too much: premature. Here's how OS X's built-in dictionary defines the word:
pre-ma-ture
adjective
occurring or done before the usual or proper time; too early
: the sun can cause premature aging | [with infinitive] it would be premature to do so at this stage.
Premature. Something before its due time, something not to be done just yet. Let's look at the quote from another angle:
If the time is right for optimization, it's all good.
If it's suitable to optimize here and now, do it. Optimization isn't premature, if it's needed, no matter when you code it. If your specification says that a certain heavy routine will be run often, but the return value never changes, there's no reason you shouldn't cache the result. You don't have to wait for a rewrite to make truly beneficial optimizations.

It's good that we have a solid definition of the word. The bad, however, is that we don't have a solid definition of what is and isn't premature. This is where your experience as a programmer comes into play. You have a gut feeling, and you should definitely listen to it. If your gut feeling was wrong, excellent! You now have an opportunity to learn something of it all.

That being said, I do think that it's better to err on the unoptimized side, than to optimize 'just in case'. It's always easier to optimize clean code later, than de-optimize the clever code you wrote.

Thursday, February 26, 2009

Designing with Typo

...graphy, that is.

It's been a while since I read a book that's worth mentioning, but here I am again, this time with The Non-Designer's Design Book.

It's rare that you read a book that would be useful to just about anyone. And when I say just about anyone, I really mean that. Not only programmers, or people interested in computers, but potentially also home moms, school children and practically anyone who might at some point of their life do anything that has something to gain from looking look and would involve some text.

The emphasis, however, is "text". I was a bit mislead with the title of the book, and understood that the book taught about design in the general sense. But, as the subtitle states ("Design and Typographic Principles for the Visual Novice"), it's very typography-centered – how to lay out text and how to choose your fonts. Just wanted to get that out from the start.

Although this book is recommended for practically anyone, I would recommend this especially to all the programmers out there. We programmers tend to be very left-brained; we like solving those puzzles with elegant algorithms, create nice structures for later use and tinker around, looking how changing this thingy alters that thingy. The right side of our brain gets suppressed quite easily, for a reason or another.

While I mainly speak of my personal experience, I'm sure there are others out there who relate with me, but when I try to present my ideas and thoughts (be it UI or even a website), I get lost, and don't know how to accomplish. I even might have a clear vision inside my head, but it never looks as nice outside of my head. This book gives very concrete, usable and easy to understand examples on how to lay out things. Even if the book uses text as its main design element, the main principles can be applied to some graphic elements as well.

I think the most important, yet easiest to understand, message this book comes across with is CRAP. Contrast, Repetition, Alignment and Proximity, that is.

  • Contrast your type readily with other elements to make them stand out;
  • Repeat some elements throughout your document/text to make consistency;
  • Align your text consciously and in an orderly fashion and not just thrown around; and
  • Place together (hence, proximity) information that belongs together.
The book has more extensive and visual explanations about these rules, so it's unnecessary for me to try and explain them here. This is the first half of the book, and, as said, the most important part. If you won't read the whole book, at the very least, read these principles, and you'll come very far, not to mention produce layouts that stand out from the mass of average.

The other part of the book explains about fonts, different families of fonts, what the basic structure of a glyph (a shape that represents e.g. a letter) consists of, and how font families can be mixed and matched. Although this part was a less generalized, and more about the art of fonts, I found this very interesting and gave me, as a web developer, much insight on choosing my fonts properly in the future.

In short, besides the misleading (to me) main title: I have absolutely nothing negative to say about this book, but only hearty recommendations. Since you are reading my blog, there is absolutely no excuse for you not to read this book (except if you already have read the book).
The fact that I don't own the copy I just read (I borrowed it from work) is kind of a bummer, since I can't just pull it off the shelf and refer to it later on.


On a more LightFrame-y note, the documentation process is progressing slowly but slowly. I have set up a GitHub repository for a reference implementation of the documentation. It uses the Git's submodule feature to refer to the documentation itself. I haven't played around much with submodules, you might need to read up on how to grab the latest version of the documentation itself. Setting up the environment isn't exactly user friendly either, so to just read on the current state of the documentation, I have put a copy on my own temporary server.

Wednesday, February 4, 2009

My Curse by Design

I am cursed. The curse is so potent, so strong, that it could affect other people. In fact, not only can it affect the behavior in others, it could even make other people less productive than how much they could be.

I know too much.

My curse is that of the Knowledge. I've long realized that I must suffer from it, because I've written all the code. I know LightFrame inside-out. The presence of The Curse has been in my rationale at all times, but I just never actually noticed anything that would indicate its grave reality. Until now, that is.

The first time that I got a vague yet concrete hint of Its presence was when I did the presentation of LightFrame at work. Soon afterwards, I realized that with not-at-all-that-much of misinterpretation, people could've missed the essential points of this project. I knew the points – I have them lodged somewhere in my frontal lobe. I simply assumed that the choices of my words in my presentation conveyed them to others, but I never really checked whether they were clear enough, once the slides were done.

Listeners might not become imbued with the niceties of LightFrame, discard it as redundant and go on with their lives. In fact, just about that did happen.

A more recent and real slap-in-the-face is the documentation process I'm currently busy with. If you'll excuse a slight detour in my writing; as I've told before, I held a brief Git workshop at work. During the workshop, I happened to make a comment about Git's documentation: [paraphrased] "The documentation can be a bit confusing and hard to get grasp of. Although it's thorough and informative, much of it is written by [the author,] Linus Torvalds himself. And that's the problem – he knows the material too well, and apparently has a hard time explaining the concepts to a person who doesn't know all the things he knows."

Well, see: I'm there now. I'm writing a non-technical manual, that should be easy to read and understand, about something I have intricate technical knowledge of. It's hard, if not outright impossible, to put yourself in the shoes of someone who doesn't know what you know.

I find myself constantly analyzing what I've written; erasing passages too elaborate and verbose, rewording sentences here and there and/or rewriting paragraphs because I'm trying explaining it from various angles. What does the reader not know? In which ways could my words be interpreted? Is this more helpful than confusing? These are the self-doubting questions that haunt me. The answer to all of these questions, more often than not, is "I don't know!"

I wish I knew less, so I could do a better job...

Sunday, February 1, 2009

Musings about Exceptions and Exceptions

Because I'm in the middle of documenting LightFrame (or what it is today), there's not much of interest to report from the programming side of things*. So, instead, I'll revisit a past musing, and how it got resuscitated with a twist.

*) Actually, there might be something I could write about the documenting process, and how I was forced to fork an open source project, to be useful for documenting. But that story has to wait...

Time for a trip to memory lane.

Almost a year ago, I confessed my confusion of the difference between PHP's exceptions and errors. In that article, I wondered why both of them exist, as they seem to do the same things, but concluded, that errors happened when there's nothing one can do to fix the situation, while exceptions give you a second chance to fix things, or at least fail gracefully.

When I re-read the article (I always love to read what I've written in the past, to see whether I've grown wiser or dumber since then), I noticed the little postscript that I left on the page: "One must wonder whether these musings bite me in the ass someday..." I was then worried that the article would give away my naïveness when it comes to error handling and/or programming. But, it turns out that the confusion between errors and exceptions is nothing compared to the confusion between exceptions and exceptions.

Java, the promised language of correctness, robustness, design patterns and exceptions, brings uncertainty of how to really use its exceptions. Let me present you: Exhibit A. Turns out that I'm not the only one wondering about the semantics of stuff.

Java has two kinds of exceptions, runtime exceptions and checked exceptions. Runtime exceptions may be thrown at any place of the code, and they can be caught, or disregarded, while checked exceptions must be caught and dealt with – If you don't catch a checked exception, the code won't compile. The question was when to prefer one over the other.

I gave my opinion on the matter: I argued that the case in question shouldn't use exceptions at all, but a return code to differ between a successful run and a failed run – a third, totally different, point of view. Funnily enough, this answer was the publicly most accepted answer at the time of writing this!

What a relief: I'm not the only confused one!

...or actually, that's not a good thing at all. I would rather have it clear-cut how to use what features. It would make everyone's lives easier, when there's an intuitive and clear separation between Method A and Method B – that there would be no question of which method to use where, because doing it The Other Way would be just stupid, dumb and ass-backwards.

Unfortunately. This isn't going to happen. There will always be nuance-differences between Method A and Method B. They came to be when a language developer encountered a situation which couldn't be dealt with in the precise manner that would be 'correct' for that particular case. So that particular case gets generalized, and it's a free-for-all for anyone to use in what ever context they wish. This is why you can do the same stuff in a zillion different ways, each just a tad different from the next one.

Monday, January 26, 2009

Gittin' Jiggy Wit It

I've recently become interested fascinated by the technology behind Git.

It has been a while since i switched over to Git – nine months to be approximate. For about seven-and-a-half of them, I treated Git as a SVN clone; code → commit → push → repeat, or CCPR for short. Just keeping the source code alive. Then something happened. I did a branch. Then I did a second one. I kept two separate branches for a while, and then merged them together (although I now know that I should've rebased instead).


Since then, I've begun to really look at what Git can do. The single most teaching experience for me was when I held a one-hour Git intro-workshop at work. Next I was discussing on converting some of our SVN repositories into Git. Next thing I know, I was installing gitosis on a virtual machine.

Today, I bought a Git Internals PDF for a reasonable $9 USD. Although I haven't had the opportunity to read the PDF itself, the accompanying screencasts (actually the same, and more, as the ones I linked to above) seemed well done and informative, although a bit on the high-paced side. But I'll be reading the PDF with gusto, as soon as I get the opportunity. I also have an article called Packaging Software Using Git in my to-read list.

There's simply too much interesting stuff to learn...