Home About EIS →

Software Engineering as Artifact Creation

if (sandWeight != idolWeight) { throw new BoulderException(); }

if (sandWeight != idolWeight) { throw new BoulderException(); }

Geek disclosure: I’ve become fascinated by the different facets of Software Engineering. Not just as a means to an end, but as a practice, as an art and as a historical artifact. I feel like I’m in Indiana Jones and the Java Temple, full of Pythons, with the riches of Perls and Rubies.

My desire for harder, better, faster, stronger code has been spurred on by being bitten one too many times by unchecked exceptions in Python, leading me back to the comfortable blanket of Java, unit testing and a framed photo of Kent Beck on my bedside table.

The Art of Programming has long been recognized and understood. Anyone who doubts it should visit 99 Bottles of Beer, a repository of all the various ways to specify a program that prints the 99 Bottles of Beer song. Here’s my favorite, in Perl (plus a module):

    ''=~(        '(?{'        .('`'        |'%')        .('['        ^'-')
    .('`'        |'!')        .('`'        |',')        .'"'.        '\\$'
    .'=='        .('['        ^'+')        .('`'        |'/')        .('['
    ^'+')        .'||'        .(';'        &'=')        .(';'        &'=')
    .';-'        .'-'.        '\\$'        .'=;'        .('['        ^'(')
    .('['        ^'.')        .('`'        |'"')        .('!'        ^'+')
   .'_\\{'      .'(\\$'      .';=('.      '\\$=|'      ."\|".(      '`'^'.'
  ).(('`')|    '/').').'    .'\\"'.+(    '{'^'[').    ('`'|'"')    .('`'|'/'
 ).('['^'/')  .('['^'/').  ('`'|',').(  '`'|('%')).  '\\".\\"'.(  '['^('(')).
 '\\"'.('['^  '#').'!!--'  .'\\$=.\\"'  .('{'^'[').  ('`'|'/').(  '`'|"\&").(
 '{'^"\[").(  '`'|"\"").(  '`'|"\%").(  '`'|"\%").(  '['^(')')).  '\\").\\"'.
 ('{'^'[').(  '`'|"\/").(  '`'|"\.").(  '{'^"\[").(  '['^"\/").(  '`'|"\(").(
 '`'|"\%").(  '{'^"\[").(  '['^"\,").(  '`'|"\!").(  '`'|"\,").(  '`'|(',')).
 '\\"\\}'.+(  '['^"\+").(  '['^"\)").(  '`'|"\)").(  '`'|"\.").(  '['^('/')).
 '+_,\\",'.(  '{'^('[')).  ('\\$;!').(  '!'^"\+").(  '{'^"\/").(  '`'|"\!").(
 '`'|"\+").(  '`'|"\%").(  '{'^"\[").(  '`'|"\/").(  '`'|"\.").(  '`'|"\%").(
 '{'^"\[").(  '`'|"\$").(  '`'|"\/").(  '['^"\,").(  '`'|('.')).  ','.(('{')^
 '[').("\["^  '+').("\`"|  '!').("\["^  '(').("\["^  '(').("\{"^  '[').("\`"|
 ')').("\["^  '/').("\{"^  '[').("\`"|  '!').("\["^  ')').("\`"|  '/').("\["^
 '.').("\`"|  '.').("\`"|  '$')."\,".(  '!'^('+')).  '\\",_,\\"'  .'!'.("\!"^
 '+').("\!"^  '+').'\\"'.  ('['^',').(  '`'|"\(").(  '`'|"\)").(  '`'|"\,").(
 '`'|('%')).  '++\\$="})'  );$:=('.')^  '~';$~='@'|  '(';$^=')'^  '[';$/='`';

(also special recognition for the version in Shakespeare)

In my reading of the wonderful Effective Java, it’s become more and more clear to me that the guidelines to writing code behind Software Engineering isn’t a really a practice of art, but one of designing an artifact to be visited later by men and women searching for fame, glory and things that belong in museums.

We worry about how other programmers will use our API, so we code defensively, assuming that invaders will somehow break our carefully constructed masterpiece. We scrawl comments/hiedroglyphics across the walls of code editors so that visitors can attempt to understand the reasoning behind the machinations of our creation. We try and match coding conventions so that even where we forgot to comment what the thing did, it should be readable enough that visitors understand that you need to put the staff in the hole which lights up where the treasure is buried. Then, when our software civilization dies (read: moving to another team, losing interest in the project), hopefully the knowledge we created doesn’t die along with us.

The most telling part of Effective Java is it often has very little to say about whether your code meets its intended function, but still manages to weigh in at about 330 pages. Good software just works. Great software works well.

When we teach Software Engineering, it’s within the constraints of a tight academic schedule, just enough to impart the important things, and cross our fingers and hope the students listened to us when we told them to design for the future. I’d love to take the idea of software as an artifact and have students implement a new feature to software created by the previous year’s students. The inevitable hurt, pain and suffering may go some way to really instilling the importance of good design. They’ll only find it out the hard way in the workplace, so why not teach them now?

Dusty fedora hats would be optional, but encouraged.

(this Software Engineering post written with apologies to Jeff Attwood :) )


About the author:  Chris Lewis is a British PhD student researching the intersection of software engineering and video game development. Read more from this author


This entry was posted in Academics and tagged , , , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

6 Comments

  1. Posted August 17, 2009 at 4:00 PM | Permalink

    I’m a bit conflicted on this, being pulled in two directions by an appreciation for a lot of the distributed artifact-building and careful attention to long-lived APIs, interfaces, maintainers, etc. that goes on in the open-source community; and on the other hand by a view that accumulated architecture is often worse than just rewriting things, and in particular, an excessive concern with it creates essentially artificial problems that then have to be solved. Sometimes, maybe it’s better to explain what you wrote and how, in text, than create the Great Pyramids of code, if we’re worried about things being long-lasting. (Or at least find a way to create simpler, modular artifacts.)

    As a general mindset, I find Yosef K’s description of nomadic v. villager programmers to be one of the more cogent descriptions: nomadic programmers write code mainly to solve problems, whereas villagers carefully farm and tend code, building it up into larger and well-designed code. Not entirely clear what the relative proportions should be.

    As for the curriculum proposal, though, I think there’s a danger of making students solve an artificial problem, which will carry a takeaway message of “software engineering is about managers making you do stupid things”. If you’re implementing some stuff on top of last year’s code, and last year’s code is both not very extensible and not doing all that much to begin with, the obvious thing to do would be to ditch it and write your stuff from scratch. The only reason to reuse code, after all, is when it’s easier than not reusing it!

  2. Teale Fristoe
    Posted August 18, 2009 at 10:02 AM | Permalink

    I love the imagery here. A couple of comments, though:

    Don’t the code skeletons and sample code provided by professors and TAs already provide students with enough pain and suffering? I would be hesitant to support a scheme with the sole purpose of exposing students to ugly code simply so they get exposed to it. Students should be exposed to well written code so they have some idea of what it is… as you say, they will inevitably be exposed to bad code when they enter the work force. Then again, maybe teaching refactoring would be a valuable exercise. I can imagine a course in which students write a single project, but each assignment is to update their previous version with more sophisticated techniques and patterns they’ve learned.

    I think your overall message is a good one, especially for the gaming community, where well written code is often a second thought (unless it slows down the action). I’ll be the first to admit that I’m guilty of this myself. I think to some degree this is inevitable, because most games have a finite scope and a thoroughly experiential goal: you write a game to play it, not to produce beautiful code that will still be functional in five years. It would be nice to at least be able to look back at five year old code and have some idea of how it worked, though, even if it isn’t clever enough to warrant translation to and publication in a natural language.

  3. Posted August 18, 2009 at 3:55 PM | Permalink

    Exposing students to the harsh realities of real life in a “safe” environment is something we already do: that’s why we have team assignments (I’m not joking).

    When I graduated, I thought that all programmers would be competent, would understand basic unit testing (if not perform it) and comment code. This was naive. If we assume we want to create quality programmers, then learning how to brutally, but safely, refactor awful code would be a very useful exercise. The pain involved would help students understand the abuse they pass down the chain if they output terrible code themselves, and perhaps lead them off that dark path.

    I do think this is only something that third or fourth years could achieve, for two reasons:
    1. So, as you rightly point out, they already know the “right” way.
    2. Such an exercise requires a confidence with programming that isn’t gained earlier.

  4. Posted August 18, 2009 at 5:29 PM | Permalink

    I suppose I’d disagree with the basic premise, that the purpose of an undergraduate CS program is to create “quality programmers”. I could see that as the purpose of a software-engineering degree (some schools have them), but I’d see a CS degree as primarily geared towards teaching computational thinking.

    Even if you want to be jobs-focused, it seems to me that it’s increasingly likely that people with undergraduate degrees in CS will end up in a wide range of jobs. Apart from the standard tech-industry-on-a-huge-codebase jobs, CS folks now end up: as web developers, as indie app developers (iPhone/Facebook/OSX apps/whatever), as researchers (in CS or related areas like computational physics/biology), as the data-mining guy at a financial or media firm, etc. Computers are everywhere now, not just at large tech companies.

    I actually don’t know a single one of my undergraduate CS classmates who works in a stereotypical CS industry job. Admittedly I went to a theory-focused program and self-selected for acquaintances with interdisciplinary interests, but there still seems to be a whole lot out there other than working on huge codebases for a C++ or Java shop. At the very least, I think students should get some flexibility in choosing which path coincides with their planned career. In a disciplinary self-interest sense, it also might be worth considering whether making CS degrees seem more like a hazing experience is a good way to accelerate the trend of plummeting enrollments. =]

  5. Posted August 18, 2009 at 9:35 PM | Permalink

    I knew someone would hook onto “CS != Programming”, and I agree, no, it does not. But Software Engineering classes are Software Engineering classes, so we should teach the realities of Software Engineering 😉 I’m talking about this very specific aspect.

    I also wouldn’t say that my work as a Database Consultant or university Computer Science support is “stereotypical” in your definition, but that’s where my experience of these problems came from.

  6. Posted September 14, 2009 at 12:48 PM | Permalink

    Yeah, I agree. Good code is written to be read. Good code introduces itself slowly and doesn’t expose more than it needs to.

    It’s a nice analogy in academe because the professor who can’t teach shouldn’t be writing code either 😉 The fancy tricks that you’re introduced to in your algorithms class are like semi-colons, they’re essential to be considered a author, but rarely get used day to day. Much more important is the long-lost art of structuring an essay (building a program to be read as much as it is built to run).

    I think the most important thing left out of undergrad programs is reading code. Good code, bad code, whatever. Reading lots of other people’s code. Assignments such as “download the kernel and find a line of code that selects the scheduler” are conspicuous by their absence.