There is a strong tendency these days to push for a reform of software education. For one, this is quite strange as I don’t consider it has ever settled and has too many variants out there to say they are all wrong, but there is still a consensus that the current state is pretty bad. Looking at the failure rates of software projects, this may well be true. Ever since the birth of the profession, a lot of things were learned about software development. Yet, the average curriculum of programming courses take very little of it into account. Most of the ads you may see focus on programming languages and environments, pretending that you will know all there is to know at the end of whichever amount years, months or weeks they decided to advertise.
There is a disconnection. Languages and platforms have very little to do with the actual skills relevant to software development and the failure rates of projects. This is why there is a call for a reform. I have observed multiple opinion groups.
There has always been a debate to compare software development to other disciplines, trying to find a metaphor to explain what we should be doing. Many of those metaphors lead to apprenticeship and the idea that we should be learning from the work of masters. The basic idea is that we should learn to read before we write. In fact, it does feel absurd that most of us wrote our first lines of code without understanding them. The act of writing it and running the code explained us what it did. Honestly, I think that works pretty well. Code at that level has very little meaning outside execution.
Fortunately, this group actually aims for the higher level benefits. We should be reading significant pieces of code to learn from the design decisions that were made. Learn about the trade-offs. The entire series of Beautiful [Code|Architecture|…] books fit in this perspective. The main issue with this right now is that we don’t have a significant corpus of code we could get people to read reasonably. So few people read code that we can barely begin to identify the good parts. Good being very subjective to start with.
Imagine a first semester course in college where students never touch a computer. They are provided with code that they must read and understand. Exams? Write essays about the code to explain the author’s intent and decisions. Find flaws and boundaries. It certainly looks like a literature course, but it’s the kind of thinking a programmer needs to have when jumping into new code. They must understand the design decisions that were made. Software maintenance is a mess right now because very few people know how to read code. They don’t know how to spot the limitations and they just hack their way through it, corrupting the initial design until it becomes a faint memory from the past.
Reading code requires a special skill called pattern recognition. Unless you can abstract away from the individual lines of code, any attempt to understand a code listing longer than a hundred lines is bound to fail. Chess players don’t see their game as a series of individual movements. They have patterns that they recognize and use to anticipate the opponent’s moves. Although we don’t have opponents (or shouldn’t have), knowing the patterns in code allows to anticipate the attributes that come along with them, including extension points, possibilities and limitations.
Design patterns, which goes well beyond the gang of four initial list, are a way to build a collective intelligence related to patterns. It’s great to know them to communicate with others, but we should also get into the habit of building our own mental models. Maybe someday to write a pattern for it ourselves, or just recognize that it already has a name when we hear from it.
Do it yourself
Almost completely on the opposite side, the DIY group encourages programmers to write their code from scratch. Write their own libraries. Their own frameworks. Clone existing applications. All of this for the sake of learning. You can spend years reading about other’s mistakes and you may be able to remember some of them and avoid them when you encounter the situation. However, a mistake you make yourself is one you will remember forever.
In writing your own code, you learn a lot from the underlying platform. Once you’ve written a framework or two, you will be much more apt to understand other frameworks as you encounter them. You will understand why some things are done in a certain way, because you will have encountered these issues yourself. You will be able to notice details in the design that no one else took any attention to, like a really clever technique to handle data filtering.
The DIY approach leads to specialization. It focuses on learning things in depth. Most open source projects started this way. The most talented programmers you might encounter probably learned this way. However, this is impractical in more traditional education. It takes a lot of time. It requires passion, and that can’t be forced onto someone. Within a few hours that would make for a reasonable assignment, very small libraries or focused tasks can be performed. However, what you can learn from scratching the surface is very limited. Going deep enough to really learn something would take months or years.
Arguably, most of the education today does something very similar to this. Teachers give assignments and students perform them. They are built in a way that the students will hopefully learn something specific related to the course along the way. Longer assignment would lead to more valuable learning, but it would also make evaluation much harder and the scope much wider.
An interesting aspect around the web in this area is code katas. Small exercises that can be made by professionals to practice and keep learning. I think that DIY is really important, but it’s really part of an ongoing personal development rather than something to be done in schools. Let’s face it. At the speed at which technology evolves in all directions, being outdated is a permanent state. The best we can do is make sure we’re not left in stone age.
The process school of thoughts is morphing as we speak. There used to be a time when there was this idea that if you pinned down requirements early on, made a good design and implemented it properly, nothing could go wrong. That’s what I was thought in college in the only course related to project management. These days, it may be XP or some other agile method. It’s still the same school of thoughts. Given a good process, you will obtain good results, so education should focus on teaching good processes and you will obtain good software developers.
Processes are great, but they are mainly a management issue. A process well adapted to the project will allow the team to perform at their best. However, there is a catch. A mediocre team performing at their best is still mediocre. Process management is an optimization issue. It’s about making sure that the ball is not being dropped in a terrible way that could have been prevented because the team had the skills to avoid it. Dealing with optimization before being able to solve the issue is a ridiculous idea. You might as well tell students to wear a suit at work to hide the fact that they don’t actually do anything.
The reason there are so many books on methodologies (luckily, the rate at which they are written has decreased) is that they all work because they were written by people working with great teams. They could have followed no process at all and they probably still would have succeeded.
Being able to follow a process is important for a developer. As they join a team in the real world, they will have to follow the rules to begin with. Basic understanding of the reasons behind them will allow them to perform better and stop them from questioning everything. However, processes can in no way be central to the education, unless you are training managers.
These days, this group is a lot into enrolling students in unit testing from the start. Teach them TDD from the start so that they will never think about working in any other way. Once again, I feel this is a lot of what schools have been doing forever. A best practice is very much dependent on time. In college, we started directly in object oriented programming because that was a hot word at the time. Sadly, just writing classes does not really provide with a good understanding of what object oriented really is all about. There is a balance required.
I would agree that TDD is a better stepping stone than just object oriented or whichever buzzword we had in the past because testing is unlikely to disappear in the future, but very few projects are written test first these days. Given that it has a huge impact on the design of software, I fear that it would make those students completely incapable in a typical work place, having to deal with legacy code.
I think that teaching best practices is certainly one of the roles of education, but it should focus on those that overlap technology and have greater odds of surviving. The buzzword of the day is unlikely to be the best choice. Perhaps the buzzword of the last decade that is still around is a more suitable choice. Those the industry does not speak of because they are part of the definition of software engineering. I don’t even count the amount of surprised faces I’ve seen after telling them that people don’t learn to do unit tests in college. That we don’t learn to use version control. We don’t get to package and release applications, or deploy them for that matter.
Using version control, releasing, deploying. Those are skills that are expected in the enterprise. They have been around forever. CVS wasn’t the first version control software out there, and people speak of it as a long extinguished dinosaur. Yet, outside those who contributed to open source software in their spare time, I know of very few graduates who know how to use subversion or any other tool. A large company I’ve worked it had a one day course for all new hires which focused almost exclusively on version control. That means that the absence of the skill is frequent enough and important enough for them for have full time resources assigned to training. Why is that not thought in colleges? I don’t know.
Sure, unit testing, test-first and TDD are great. But perhaps there are more fundamental things to go through before.
But really, is software education all that bad and does it matter anyway? There is some pretty great software out there, and there are excellent programmers who learned without ever going to school. There is certainly a need to shorten the training period from 20 years to 3, but experience will always have value. I’ve learned programming by myself. I must have been 12 or 13 when I wrote my first line of code and probably would have done it younger if I had access to programming tools or internet before that. I could navigate a computer with a DOS prompt before grade school, so I really don’t see why I wouldn’t have started programming earlier given the opportunity. Learning to program is not that hard. I went for a technical degree in college (3 years) and then for software engineering in university (4 years) afterwards and that thought me a whole lot, but I still could program a web forum and knew basic SQL before entering college and what pays my rent is what I learned from contributing to open source.
One can easily learn to program by himself, especially now with an unlimited amount of resources available. If there is one thing school can do, it’s distill all the information to help focus. The real question that should be asked is what education is trying to achieve. I really don’t think that education has anything to do with being a good programmer or professional. That’s a question of passion and attitude. Most book authors I respect probably studied something unrelated because there was no such thing as software education in their time. No matter what you put in the educational system, passionate people will end up on top. Don’t even think that can be influenced or that they can be manufactured.
If the goal is to provide workers (which it probably is, from the government’s standpoint), they should provide a training that allows graduates to hit the ground running in a workplace. That means providing them with techniques to understand large code bases and work in them efficiently, and to teach them to use the tools people really use. Then it’s all about learning to find the information you need, from valid sources, when you really need it. Most code out there does not use complex short path finding algorithms. Sure, knowing those and all the concepts of complexity is useful, but not crucial. When you need it, you have to go back and search for it anyway.