When I was younger, my uncle had this huge box of legos. When I'd go over to visit, we'd get them out and build with them. He always made these great constructs, planes, and cars and buildings, and the like, whereas I made these ungainly little things, all mismatched colors and assymetrical wings. I think that a good deal of the difference was that they were his, he'd seen the box, and knew what could be done with them, whereas I just had what I could visualize from the myriad pieces of little colored bricks stuffed together in a brown cardboard box.
A few weeks back, I read this article (Bricks) that states that software is not made of bricks. The main thrust of the article is that while some programming metephors compare software development to physical architecture, the reality is somewhat more complex and instead of looking at software as something that can be defined up front with a set number of pieces and construction time where just moving bricks to the construction site can be a help, you have to look at it from a higher viewpoint where the project is more than just the architectural considerations, and the laying of the bricks is the only consideration. The best way I could think to describe it to a co-worker is that if you're going to compare software to brick-building, it would be like having the bricklayer have to stop, and make his own bricks sometimes, and each brick that is made might have to be hand-crafted from different materials.
Of course, the first comment in the article would be a rebuttal comparing programming to legos which states: Usually I started with some idea in my mind of what I wanted to build (a plane, a spaceship, a robot) and then scrubbed the heap of parts looking for the right ones, and slowly assembly them together into bigger ones (always spending a significant amount of time looking for the right piece) until I created something that wasn't what I envisioned originally, but at least could pass for it :-D. Both analogies stuck with me, both felt right, yet something was missing.
Recently I've been doing a lot of programming in WPF, both as a learning exercise, and to apply some new techniques to a five year old program that I never could get right under Windows Forms. Things just "clicked", the code came together, and the new programs are working well. As I was sitting there trying to visualize the process, I had a Numb3rs moment. The end result of programming is very fractal in nature. On the surface, you see a construct (simple or complex, depending on the program) made up of building blocks. As you zoom in on each component, you'll see that it is it's own construct, with it's own building blocks and definition, and so on. You can continuing zooming down until you reach the machine code, and you can go deeper still if you want to change paradigms. And much like viewing a fractal, it may look simple on the surface, but as you delve down, you see the complexity in each piece, a little fuzzy around the edges where it doesn't "quite* resolve, where the line between your code and the APIs blurs.
Nowadays I don't work with Legos, but I do build things that soar. Sometimes it's pretty easy to see which building blocks are in the API, sometimes the line really does blur. And every now and again, there's just no piece to do what you need, and you have to jam in a big Duplo block cause it's the only thing that'll work...