Saturday, May 12, 2012
The Art of Computer Programming
Have you ever heard that computer programming (and by extension, Software Engineering) is an act/profession that doesn't require any imagination or creativity?
I certainly have, but such comments tend to be made by people with no knowledge or experience in the field, so their ignorance can be (at least partially) forgiven.
But as such, it prompted me to write an article about why this is untrue; software development does indeed require imagination and creativity, in fact, quite a lot of it!
It's not too difficult to see how such an option might evolve among the common populace, if you look at the "stereotypical" view of a software developer in society, you'll find a person (often male), wearing a white collared shirt sitting in dull, grey-looking cubical typing on a dull black computer with meaningless lines of white (or green if you are really lucky) text on the screen. How could someone in such a boring-looking world possibly have any sense of creativity?
If you examine software developers in real life, you actually find a much different perspective. But I digress, this article isn't really about the people, it's about the work itself. There is another common misconception about programming: that it is completely formulamatic, and that programmers just go through the motions dicated from a book or a superior and somehow miraculously end up with a perfectly working program. Nothing could be further from the truth.
Imagination can be defined in serveral ways, but to me, it typically refers to the ability to create images or sensory input in one's mind. For example, I can picture what a peanut butter sandwich looks like, without my eyes actually seeing in. I can recall what it smells like, what it tastes like and what it feels like to hold. I can ever hear what I sound like while chewing it.
But this is only the memory aspect of imagination. There is a whole other layer of imagination on top of it, namely, the ability to create things that you have never actually experienced.
For example, I have never been to the Eiffel tower, but I can imagine standing on top of it. I have never been in space, but I can imagine floating in midair.
Our imagination can dream up things we've never thought of before, like the plot of a novel or a "Eureka" moment in a discovery. These ideas use building blocks to create something completely new. This also leads into creativity, typically the creation of something new, where "new" depends on the domain of what's being created.
Returning to the theme of developing software, there are many aspects of which require imagination and creativity, for example:
1) Imagining the finished project from high level sketch. The idea for the a piece of software typically comes form one of two places: a) Your brain; b) Someone else's brain. If you come up with an idea for a piece of software (perhaps because it's something you need, but doesn't exist yet), then you clearly exercised creativity. But even if you are developing the idea for some else, you still need to exercise your imagination and creativity. For example, in both cases you exercised imagination to envision the new software even though you've never actually seen it.
Descriptions of software to be developed tend to start as extremely abstract...just a setence or paragraph on what the software needs to do without any idea of how it is going to be done. It is up to the developer to figure out how to get there, by imagining the finished project. The developer might even come up with new things the software should or needs to do that the client never even thought of. Software gets very complicated very fast. For example, there can be many programs (not just one) involved, and communication between them, as well as documentation and many rounds of testing. Sometimes, it even takes creative methods to get the client to tell you what they need in their software, since often, they aren't sure themselves!
2) Building a cohesive whole from primitive building blocks. Computers have evolved over the years from lights blinking on a box to complex machines capable of displaying millions of pixels or performaing trillions of operations per second. It is extremely rare that any piece of software developed today is built entirely "from scratch". If software always needed to be developed from completely scratch, we'd still be using boxes with blinking lights and flipping switches to represent binary input. Over the years, software developers have add layers of "encapsulation" onto the basic circuitry inside a computer. Primitative building blocks that allow us to make the computer do something useful, for example, moving a piece of data from memory block to another, or turning a specific pixel a specific color.
When you go to develop a piece of software, you need to carefully understand the requirements, and then figure out how to combine the primitive operations available to form a cohesive whole. And sometimes you don't have the building blocks you need, so you have to find them or create them, using even more primitive operations.
Software is all about layers and building from smaller blocks. It's like when you were a child playing with your first batch of Legos. In the box, they are just thousands of individual blocks, useless by themselves. But when you combine them with imagination and creativity, you can combine those blocks in an astronomical number of ways to form something completely different. Building software is much the same, and without imagination, you wouldn't be able to combine them together to create something useful, nor keep track of the building blocks the software requires which can easily number into the millions.
3) Visualizaling what the ones and zeros actually mean. It can be hard to imagine to the novice user, but even today, at the heart of computing is nothing more then the manipulation of binary data, that is, ones and zeros (binary digits, or bits). And yet, when you look at your screen, you see text, buttons, pictures, even videos. And yet, it's ALL just ones and zeros. When a programmer is creating a piece of software, they continually have to imagine what that data, the ones and zeros, actually represents. Now, there are building blocks to help, some of the most primitive operations the computer provides are used to interpret once piece of binary data as another, for example, turning a group of bits into the letter 'A', or the number 65, or the color of a pixel. But you can't lose track of what it is underneith, and to visualize ones and zeros forming a picture of a beautiful sunset certainly requires imagination.
4) Solving problems in creative ways. Solving a problem or problems with software usually requires solving a bunch of smaller problems, then combining the solutions of the smaller problems together to solve the big problems. Each smaller problem is usually solved with a concise sequence of logical statements often mathematical in origin. The same task can usually be done in many different ways, using different sequences of logical statements.
Navigating a logical sequence of statements is rarely trivial, whether you are writing it or reading it. At each stage, you have to clearly imagine what that statement means (sometimes in terms of the ones and zeros in the computer, sometimes visually like boxes and pipes) and keep it in your minds eye for hundreds or thosands more logical statements you are writing to make it make sense.
The ability to break the large problem up into smaller problems takes a lot of creativity, and solutions to the smaller problems themselves are often far from obvious.
5) Development of user interfaces. Programmers rarely write programs which just do a single thing, all the time. Most software is capable of performing many different tasks, and requires input from a user, which can be entered an enormous number of ways. So not only do programmers have to write the software to perform a funtion, they need to envision a way to let the user tell the software what to do.
A lot of software today provides a Graphical User Interface (GUI, pronounced 'gooey'). Creating a good GUI is a subject of much discussion, and can be considered an art form all on its own. The operating system you are using now (likely, though perhaps not) includes a GUI, as does the web browser you are reading this page on. It took a lot of time and creativity on the part of the devlopers to figure out how to make the GUI work well and be usable. And even then it's difficult, because a devloper will tend to write a GUI that a developer wants to use...but often that isn't sufficient for the non-devloper. As such, they have to imagine what it's like to be an average user, and create the GUI for them, not themselves. Stepping outside of yourself like that is not easy, and requires a lot of imagination. Even software which provides a non-GUI interface, like a text-only interface (yes, they still exist) needs to think about the user, and figure out a good way to describe all of the functions and operations of the software through text only.
6) Breaking software. You might be suprised to learn that an important job of a software developer is actually trying to figure out how to break the software, let alone figuing out how to write it. All professional developers want their software to be completely bug free, but in reality, that goal isn't achievable. Still, as perfectionists, we strieve to make our software the absolute best that it can be, and one possible metric by which to measure that is bugs. Bugs (and sometimes new "features") typically happen because the user does something with the software that the developer didn't ancipiate, and so the software does something unexpected.
In fact, software development companies have entire departements dedicated to testing and trying to break software, sometimes these departments are even bigger than the developent department. And they are effectively programmers themselves, just doing a different kind of programming. One job is to write their own programs, specifically for the purpose of testing the product program. If the software is supposed to do things "A","B" and "C", then they write a program to exercise A, B and C in different ways, then check that the software preforms as expected.
But, it's also their job to imagine ways to use the software in unexpected ways, and see how the software reacts. Such a task requires you to create inputs entirely from your imagination, and sometimes to break the software you need to get pretty creative, depending on how well the original developer considered the possible inputs. For the programmer, tracking down bugs and figuring out methods to fix them while maintaining the integrity of the software is a strong exercise in creativity and imagination.
7) Documentation and help files. Software is useless unless you have a good way to tell the user how to use it. Developers also need to write extensive documentation on the software themselves so they can use it as reference material when updating and changing the software.
A GUI can only hold so much information, so most software typically has a Help section. The Help section describes all of the software in greater detail, so that the user can understand it at a more basic level in order to decide how to perform tasks. Writing this documentation requires you to imagine how the software will work, and what it looks like, especially since the person writing it might not have developed it. It's also important to organize how the Help appears so that it is accessible to the user.
The documentation of the software can number into the thousands of pages and also needs to be well organized. Having creative ways to store and reference this documentation so it can be recalled by the developers when needed is critical. Trust me, you don't want the developer of a nuclear power plant's software writing code without a clear picture in his or her head of what it's going to do!
8) Considering the pace at which technology changes, and anticipanting future needs. Technology moves very, very rapidly. As such, professional software is almost never just a |one-off" peice of work which is never touched again. Software evolves over time, and when programming, you can't just consider what the software needs to do today, you need to anticipate what it's going to need to do tomorrow, the next day and the day after that. Some software systems survive for decades after their original developement. If the original developers of the software hadn't had any imagination or creativity, they wouldn't have been able to build the software to evolve, and have to be constantly replacing the software. But, in reality, developers build software to evolve, to live and to grow.
Even this list is hardly exlusive, a professional programmer could probably add a few more ways on top of the ones listed on how programming requires creativity. Just because we might (emphesis on the might) not be able to paint a masterpeice or decorate a house hardly means that we lack imagination and creativity, it just means that we express it in different ways.
I hope that this blog post has been enlightening to you, and encourage you to consider all the imagination, creativity, and hard work into the software you use everyday. Today, the world runs on software, and that's unlikely to change any time soon. Considering all of this, why one would think programming doesn't require imagination and creativty, especially when it's something they've never experienced, is beyond me. Or at least, beyond this particular blog post :)
Take care, and have a great day!