Posted by timboudreau
on January 9, 2006 at 9:41 PM PST
Today I read a Swing tips entry which had some spectacularly bad advice in it. I posted a rather strenuous reply saying "You really, really, really don't want to do that." It got me thinking about how one's sense of the good, the bad and the beautiful in programming evolves over time.
(I wrote this a few months ago, but delayed pubishing it so as not to implicate the tech tip author I mention)
Today I read a Swing tips entry which had some spectacularly bad advice in it - replacing the AWT EventQueue as a way to do something trivial you can do without altering the guts of the entire windowing toolkit. I posted a rather strenuous reply saying "You really, really, really don't want to do that."
After I wrote it, I had some shopping to do. As I drove, I found myself thinking - there was a time when I would have been on the opposite side of that argument. That got me thinking about how oneâ€™s sense of the good, the bad and the beautiful in programming evolves over time. I can't say my experience is the same as anyone elseâ€™s - but I wonder what parts of it are common to many people who have spent some years coding. So I'll try to capture how I've experienced this - the observer and observed being one and the same - in whatever language loosely feels right. If it resembles your experience, let me know.
The thing that I find beauty in is different from project to project. When I put together the Wizard API it was going after the cleanest, lowest profile possible API for a known problem; when I rewrote the output window in NetBeans, it was how to optimally use NIO and the text API to have a component that could wrap and scale to hundreds of megabytes of text without a hiccup, be blazingly fast and do as little bookkeeping as possible. It doesn't have to be inside the code either - I've written things where the challenge I set for myself was to create the most intuitive user interface possible. I've got a cute little framework for managing actions for Swing apps, which arose from my earnest desire never to write or read another anonymous inner Action or ActionListener class. The thing that is beautiful is the thing that challenges me - the place where I'm pushing against the limits - the limits of what will be different every time.
Pushing against limits is the key. That determines what Iâ€™m going to be proud of in the result. And limits are key. Why is a saxophone almost always more expressive than a synthesizer, when the synthesizer can produce an potentially unlimited range of sounds? Because the limitations of the saxophone force the player to work within tight constraints, and be expressive anyway. The saxophonist has to work hard. It's easy to write free verse that communicates whatever idea you want. Saying the same thing in a sonnet and not having it sound ridiculous or forced - that's hard. Greatness is when the work escapes the boundaries of the form. The reason the movie Unforgiven is a masterpiece, IMO: it takes every trope of the "western" and stands each one on its head â€“ it is the definitive anti-western â€“ yet it is also still a western.
I find that starting a project involves a sort of mental bearings-taking - exploring the conceptual space of the problem, finding where the limits are - finding the thing that needs to be beautiful, the thing that will engage my passion. It's settling into the problem space, getting to know where the where the walls are, getting comfortable in the furniture, getting an idea of what kind of construction this space wants to contain. By the time that's done, most of the code is going to write itself - now the joy is in discovering the subtleties. Coding for me is very visual, in an abstract way - I can't quite describe what the
for loop that's calling the method I'm editing looks like, but I can quite definitely see it chugging away, and so on back to what all the parts of the application I know of are doing.
When I was a teenager, one of my favorite coding tricks was to see just how much logic I could condense into a single line of code. The ongoing challenge was to see just how much I could do in how little space. A particular favorite was resolving booleans to 1 and -1 and then doing various math tricks with the result. I think I was 19 before, when fixing a bug, after spending two hours trying to decipher what one inscrutably complex line of my own code did, that I decided I'd better get my coding thrills some other way (if you've ever coded like this, you'll enjoy the story of Mel ).
It involves ego. Whether it's the gratification of creating something I use the word "beautiful" to describe (and it may only be beautiful to me), or the gratification of being clever and pleased with myself, or the gratification of knowing someone else will enjoy using what I have written, or the gratification of creating a UI that users will find intuitive and love. It might all come from a desire to be loved or appreciated, or just to do something meaningful, to have certain knowledge that I have made a difference. Ego is not a bad thing - we would be poor creatures without it.
The study of inspired error should not engender a homily about the sin of pride; it should lead us to a recognition that the capacity for great insight and great error are opposite sides of the same coin - and that the currency of both is brilliance - Stephen Jay Gould
One era in my sense of beauty was the hack phase - where the beauty was in getting a piece of software to do something its designer never thought of. It can manifest in brilliant hacks, uncovering that some library or utility has a whole new vista of possible applications. It can manifest in evil hacks, where I'm doing the equivalent of wrapping a toaster in tin foil and using it to make coffee, because a coffee pot is a thing that makes things hot, and so is a toaster. There is a real sense of mastery that is very gratifying when they work. And there is even a place for them - its a kind of resourcefulness that's very useful in "get this working again or be shot at sunrise" situations. And I think that was the sense of beauty that led to the terrible advice I read in a programming tip this morning.
API design is a whole parallel world to straight programming, which has its own aesthetics and rules - it's the meta-space around any problem space where what you write has to interact with other things. I know my sense of what's right and wrong, good and bad, has evolved enormously in recent years, and continues to. If you ever get a chance to work on a large codebase with a long history and lots of APIs, take it. It will make your outlook grow in unexpected ways. The beauty in API design is how to design it so users will enjoy using it, and at the same time leaving the API clean and small, with room to grow and evolve without breaking anything. It's an excercise in practicing kindness and decency both to the people who will use it, and to yourself, for you'll have to maintain it; and at the same time designing an API that's complementary to what the computer will phsyically need to do to accomplish whatever the task is (the Responder pattern in Cocoa is a lovely example of doing all three of these things).
I have found a different thing to be that-which-is-beautiful in every project I've ever done. I don't know that the same thing can be beautiful to me in the same way twice. But each solved problem becomes a piece of mental tooling I can use with confidence in the future. Today's brilliance is tomorrow's boilerplate, and I wouldn't have it any other way. What would be tragic is to become stuck, to stop evolving â€“ if the code I write two years from now looks just like what I would do today, something will be wrong.
I think if you work as a programmer, and you master your sense of beauty, so that you can find the thing that is there yearning to be born in any project, youâ€™ll never have to "work" another day in your life.