Wednesday, March 27, 2013

Knowledge work is a lonely activity

Performing work on a computer is a mostly solitary activity. One can generally only reflect on one’s own experiences. It is difficult to get inspiration and learn from others. Because of the nature of our work and the tools we use it is as if we software developers go out of our way to hide how we do our work.

Imagine if you were learning to play chess but you could never play against anyone but yourself. One cannot expect to become a great chess player without being able to watch masters play the game. After they leave school many software developers are left in this situation. It is not so easy for others to watch and learn from knowledge workers doing work on a computer because working in front of a monitor in a cube is not an inviting learning environment.

The software development community is in need of tools that open up the development process to encourage learning by team members. It is critically important to:
  • get feedback from ‘masters’ about our work
  • see how developers leverage good decisions and extend their position from them
  • see how developers recover from bad decisions
The learning dilemma
Software developers need to be continuous learners to keep up with changes in the field. Young developers fresh out of college have decade’s worth of learning in front of them. The questions that I am interested in are:
  • How do software developers learn about the systems they are hired to work on so they can be effective members of a team?
  • How do software developers learn to be better programmers after they have left school?
Software developers have an incredible amount of information to learn over their careers but not much structure and guidance to acquire that knowledge. This is the learning dilemma. Some of the techniques that developers use to learn about software development after they have left school are:
Try, then fail, then fix
Failing at something followed by remedial work can lead to excellent gains in knowledge. However, this knowledge can be painful to acquire. Perhaps the most insidious characteristic of this type of learning is how difficult it is to impart the hard earned knowledge on others. Only the developer who makes the mistake and fixes it learns.

Read books and blogs
Books and blog posts on the subject of software development are great tools for professional developers to learn. However, not every topic has a high quality book or blog post written about it. Invariably, each developer encounters some level of specialization where finding reading material is impossible.

Read code
One might think that reading good code is a natural way to learn to become a better programmer. This can be tricky, however, because most developers read code left to right, top to bottom, jumping occasionally to other functions and files. But, how often is code actually written this way?

When writing code it is common to touch many different parts of many different files. The order of the additions and the deletions has an impact on how a problem was solved. Existing version control systems do not record enough of this information.

Code comments could be useful for telling a story about a system but they are not always the best place to record historical information. For example, if a developer is changing the name of a variable from ‘age’ to ‘yearsExperience’, they could write a comment about why that change was needed. That comment is really only relevant to the people who knew the old name and are interested in why the old name changed. Developers who never knew the old name are not interested in that comment. So, most developers would not write down that information anywhere.

Commit logs
On check in, developers write a commit message to the version control log. These logs could help animate the changes in a group of files if developers wrote good messages. Unfortunately, they do not. It is very difficult to write a complete description of all the changes that take place from one commit to another. Remembering and describing why we make a set of changes in a commit message is almost as hard as writing the code itself.

Code reviews 
Code reviews are an excellent way to learn from one's peers. Some of the best discussions I have ever had about software engineering have taken place in code reviews. There is a significant drawback to code reviews, however, the team only gets one chance to perform the review. If one is not lucky enough to be in that review they miss out on all the learning that takes place there. Ideally, a narrative about a code review would exist that all developers could consume.

Q&A sites
Question and answer websites that target developers and programming problems provide good opportunities for learning. One criticism of these opportunities is that they only happen when a developer is stuck. In other words, the sites provide only reactive opportunities to learn, not proactive ones.

There are clearly many people who are willing to help provide these reactive learning experiences. The people who answer questions have different motivations. Some genuinely want to help others learn something about software development. Some are building reputations that they hope to leverage professionally and some are supporting specific products. Regardless of why people choose to answer questions, they should have a chance to be more proactive.

Why don't we record more?
I have been working with my students on a new version control system that captures very fine-grained, textual information about coding sessions. It allows the sessions to be played back so a developer can tell a story about their code. These stories form a new type of program documentation that can be viewed by team members to learn about the systems they are working on and to learn how to become better developers.

I have had discussions with professional software developers about how our tool records every single keystroke and makes it available to be played back. Some are afraid of others being able to see all the mistakes that they make. Some have even asked if there was an option to 'turn off' the recording of data. 

I try to explain that all developers make mistakes and that there is value in a lot of those mistakes.  One can teach their colleagues by walking them through the misunderstandings and misconceptions they had of their system. Most of the mistakes I make are due to an incomplete understanding of the requirements, the existing system, or the algorithms being used. If I am having trouble understanding these then surely someone else might be too. Why should we all have to suffer through the same painful discovery process? 

If we recorded more data about the programming process and provided stories about the reasons why things were done a certain way it would be easier for us to teach and learn from each other. Knowledge work would become a less lonely activity.

Monday, March 25, 2013

The right way and the wrong way for learning a thinking person's craft

I have been teaching computer science to undergraduates for more than ten years. Lately, I have had a sneaking suspicion that I (and the rest of the world) am doing it wrong. One learns to write good software by first writing a lot of bad software. Then, one day, after having written a lot of code, one becomes good enough to write software professionally. For me, I first felt qualified to write software professionally at least one year after graduation. During that year or so I was paid very well to learn how to do it right. I am very grateful to the company that subsidized this learning experience for me but I have a feeling they would have preferred hiring someone ready to make a lasting contribution on or around day one.

Why aren't most freshly minted computer science graduates qualified to write code professionally?
I believe a fundamental problem with the typical undergraduate computer science curriculum is that it breaks its learning units into discrete, relatively non-overlapping units that don't emphasize an integrated, hands-on approach to learning the craft. It drives me crazy when a student asks me about the syntax for creating an interface in some programming language because they have not actually done it since their OOP class. Similarly, I feel like I haven't done my job well when they ask me how to spawn a thread because they haven't done so since their operating systems class.

Writing software is a craft. One definition of craftsman is "one that learns by doing". Cabinet makers do not take separate courses on framing, drawer construction, and finishing and then wait until they leave cabinet making school to build their first cabinet. They learn those skills by spending several hours each day practicing them. With all their other responsibilities, I would guess that the typical undergraduate computer science student does not spend several hours a day, every day, writing code. They don't, but they should. We should expect them to do that. We should set up an environment where they can do that.

Should software development be taught like a trade like cabinet making or plumbing?
An argument can be made that there should be trade schools that teach software development. Perhaps it should not be taught in the same higher education environment that students learn mathematics or biology. There is a growing movement to train software developers through mentoring and on the job training. 8th Light in Chicago is an example of doing this well.

However, writing software is a thinking person's craft. Having been around software developers for more than 15 years I believe that those who receive a liberal arts education are more interesting people. They work better with others. They are better readers, writers, and communicators. They have a distinct advantage in all of the 'soft' people skills that are as important as the 'hard' technical skills. We should not deny computer science students the opportunity to grow in these environments. This is the dilemma- software developers need a mix of a craftsman's education and a traditional college education.

The right way
If I had no restrictions in setting up a new curriculum for computer science students these are some of the things that I would do to mix learning styles:

Students who are interested in computer science will start with the traditional sequence of introductory  courses in their first two years. They will take other courses to meet full time status. In other words, there will not be any difference for freshmen and sophomores studying computer science in this new environment than in a traditional environment.

Then, after a student has committed to studying computer science, they would transition to a mix of a traditional and a craftsman's learning environment during their final two years. Students will spend at least four hours a day, five days a week, for at least the last two years of a four year education working:
  • with a mentor
  • in a lab on campus dedicated to the craft
  • with changing team members 
  • on different projects both large and small
  • during the summer (if not interning for a company)
During this mixed time, students will take one or two non-computer science classes in their off hours. Students in the program will be assessed for roughly the same knowledge as in a traditional computer science environment. In other words, they will need to know the same information about networks, operating systems, databases, etc. as a traditional CS student taking individual courses on these topics. However, they will have to learn about them through the projects they are working on.

A college would have to set up an entity to take on projects for the community, local schools, for departments and programs within the college, for churches, for local government bodies. This would be the epitome of technology-based service learning. One side effect is that it might attract more women to CS. Women are generally attracted to solving real world problems whereas the men are interested in technology for technology's sake. Everyone would start out working on someone else's open source project. Eventually, everyone would create several of their own open source projects.

Occasionally, I have excellent students who don't have a lot of interesting work to show potential employers. With this model, upon graduation, every student will have a real portfolio of work to show potential employees and real experience working in a group.