Let me start by telling you a story about a hotshot programmer.
Like many kids, he started out self-taught: BASIC at age 10; FORTRAN at 13; Pascal and LISP at 15; C, Prolog, HyperCard/SuperCard at 16; Scheme, CLIPS, and SML at 17; etc.1 The kid had some very talented classmates2, and they were also hotshots.
When he was 18 or 19, the boy decided that he really wanted to study computer science. As such, he went back to read about C++ (which was pretty new then) and Smalltalk (which was an ancient classic among object-oriented programming languages, even then). His advisors warned him that retaking Intermediate Programming as a senior would leave him bored and might waste his time, but he loved it. With three of his best friends3, he whipped up a project that really impressed their instructor.4
The boy went off to graduate school. He spent five years earning a Ph.D. in computer science. During his first year, he studied programming languages and learned a lot about how little he really knew. For the next four years, he worked on half a dozen research projects, some of which involved nearly two dozen programmers.
During this time, the kid learned to:
- look up programs - both standalone binaries from SIMTEL5 and sources from USENET, Dr. Dobbs' Journal, and many textbooks
- loop up algorithms - in textbooks (in those pre-CLR days: Sedgewick; Baase; Aho, Hopcroft, and Ullman), JACM, ACM Computing Surveys, IEEE Computer, etc.
- give his code to others and work with them to correct interface errors
- publish his code as open source, and give assistance to other users
- manage other programmers and coordinate common interface development and project integration
- design a good-looking graphical user interface (GUI) for visualizations, multimedia, and other applications
All in all, an unremarkable story so far.
Well, look at what abilities I haven't listed:
- document his sources for others using plain or typeset manuals (TeXInfo, LaTeX/PS/PDF), inline documentation (JavaDoc, DOxygen), UML-type class, sequence/interaction, and use case diagrams (RationalRose, Poseidon UML), and literate programming
- maintain a stable application programmer interface (API) that others can rely on not to change without prior notice and that will still be there, in a downward-compatible form that is still comprehensible to users and developers (including the author), in a year
- build a standards-conformant GUI that can plug into a suite of tools, adapted into a framework, or for which standard GUI library components or widgets can be substituted
- keep a wishlist - i.e.,, maintain a prioritized checklist of features that were requested by other users besides himself
- refactor for convenience - adapt or repurpose code to tune it for "most-frequently used" functions (especially "every module or class in this collection requires X method")6
These are skills I've been working on developing in the 5.5 years since I got my Ph.D.
(Yes, doofy reader, the boy was me. :-D)
1 Yes, that is a bad start. It's also a typical one. Hold your hearses and bear with me.
2 Sandeep K. Singhal (now a Stanford Ph.D. alum and a professor at North Carolina State University), Dave Troy (founder and CEO of ToadNet, Inc.), and Jeremy Elson (author of CircleMud), if you know them.
3 The aforementioned Jeremy Elson, the redoubtable Eric Krody, and the whip-smart Alison T. Lai. Do you folks still remember me? :-)
4 Hi, Mark! Long time, no see! How are you doing? (Time for a web page update, perhaps? :-))
5 That's right, boys and girls, SourceForge and CodeArchive did not yet exist. Neither did CiteSeer and Arxiv.
6 I personally think this has been one of the main failings of Java to date: I've always been a big proponent of generic polymorphism (templates in C++) and am glad that Java 2 v1.5 has them (not that I have used them in Java yet).
Working with a team of student developers has been an exercise in patience and reminding myself not to ask people to do what I haven't been able to do myself. Most of them are much more efficient coders than I am, but I see the same backtracking, obsolescence, second system effects, and deadline slippage due to mismatched APIs that I experienced as an undergrad and grad student.
Now, as an exercise: Can you think of any ways, in addition to setting aside time for them, to instill the second list of habits in student developers? Our department's software engineering faculty use grades and MSE program requirements as the carrot and stick; the rest of us, unless we are serving as MSE advisors or committee members, have no such recourse.
I'm also interested in hearing what other skills you all think are essential for team environment. We IT people work remarkably poorly with others, IMO. In my experience, that's the case whether we are true software engineers or not, and whether we are working on computer science problems or more applied computational problems.