During our second semester, we were introduced to functional programming. At this point, many students had only just taken their first steps with object-oriented programming and were overwhelmed by this new and entirely different way of writing code. Many did not get an appropriate chance to fully understand the first concept they had just been exposed to, and this rapid succession of new paradigms hurt their understanding of both.
Understandably, this lecture’s failure rate was incredibly high. Of the 364 registered participants, more than 68% failed the exam, many by not showing up. On the other end of the spectrum, only 8.5% got a B or better. This is unacceptable should not be written off as an unchangeable characteristic of the field.
Our professor was quick to direct all blame to the students for not preparing well enough and not putting in the required effort. While this may certainly be part of the reason, it is merely a symptom and not the core of the problem.
From my perspective, being a student with years of professional experience prior to enrolling, this false attribution of blame does way more harm than good. In this post I point out some of the problems with the way programming has traditionally been and is currently being taught. While most should be obvious, it appears they are sometimes forgotten by those who have been in a teaching position for a while.
It is not my goal to single out a specific professor or lecture. In fact, the same phenomenon appears in many lectures that contain some degree of programming. You can also observe it outside of college in many books, tutorials and screencasts.
This one gets attached to many entry-level courses. While usually true for the first lecture, come the second week it feels as if a “but you better understand everything we say immediately” has silently been dropped from the expression.
Many newcomers are initially interested in programming merely for the sake of programming, not for scratching an itch they have had for years. They first need to fully comprehend the tools at their disposal in order to be able to find ways to use them to their advantage. If they do not understand the basics, they will have a hard time with more “advanced” features.
It appears as if sometimes “knowledge” and “understanding” are being mistaken for the same thing. Students may not need to know how to program, but they are expected to understand what it is and how it works based on very little introduction.
Wanting to rush through the basics is understandable from a lecturer’s point of view: you know of all the amazing things you could do and want to solve problems more interesting than “Hello world” and calculators. But since the first steps are crucial ones, you should always assume that large parts of your audience have not yet come into contact with programming at all and do not have the slightest idea of how it works.
Giving examples on how to solve a problem is great, but useless if students do not understand why the problem is a problem in the first place. In order for them to be able to transfer the solution to similar situations, the motivation behind it needs to be painfully obvious.
Not once have I heard a lecturer adequately explain the “why” behind an approach in a way that would be satisfactory to someone not familiar with the domain of the problem. They tend to explain technical aspects in detail, which do not mean a thing to many novices.
This often results in students not being taught how to think about problems, but how to solve a very specific one. This leaves them unable to draw parallels between a new and previously showcased situation.
We need to present problems that students can relate to in order for them to see why they would want to solve it a certain way. If the initial explanation is memorable, making the connection between two similar problems is going to be easier later on.
I usually explain custom datatypes in SML by talking about Pokémon. When introducing functions and the concept of DRY, I figuratively burn down a kitchen. While these examples may not work for everyone, their power lies in the obvious connection to the real world, which is where beginners are coming from.
If students are able to make a mental connection between a type of problem and the appropriate solution, variations of said problem are going to trigger that connection much more easily.
If your exam has a high failure rate, blaming the students and their inability to learn is only going to make matters worse. If you are doing homework assignments and notice a decline in answers being submitted, do not assume they became lazy and do not want to understand what they are being taught.
Chances are they do not get what you are trying to teach them, have deemed themselves stupid and simply gave up. They might try a second or third time, but having too many of these disheartening experiences is going to turn most people away from programming.
There are too few small wins in the early stages of programming, at least in the traditional educational environment. Those trying to read up on a subject before moving on end up falling further behind and are soon faced with the impossibility of ever catching up again.
The only way to keep struggling students going is to offer them a continuous stream of minor victories. If this means slowing down and stretching an introductory lecture over more than a few weeks then so be it. If you actually want people new to the field to learn how to program you cannot expect them to do so on your schedule.
Terms like “function”, “parameter”, “object” or “design pattern” do not mean a thing to a novice. Unfortunately, this holds true even after several semesters in more cases than you would expect.
This is not because students are unable to grasp the concepts behind these terms, but because there are too many similar-looking things with unfamiliar names they are expected to remember. Many end up getting them confused, not understanding what any of these things mean or do.
If students have never written code before, they cannot know the problems these concepts solve. Unless they feel the pain of not having them at their disposal, trying to remember and recall them is almost impossible.
If you had them run into problems by writing code without these tools first, their individual benefit would become apparent immediately after their introduction. Each would allow the students to solve a problem they themselves have had, which turns abstract concepts into powerful tools. The mere presentation of their existence cannot possibly do that.
The main point I am trying to make is that beginners‘ courses are not usually aimed at beginners. If we want to introduce more people to our profession, their first impression cannot be one of not being welcome.
We need to reconsider our audience and be more inclusive towards people without any prior knowledge. Programming has to be fun and achievable in order for them to want to keep going, not complicated and intimidating.
While awful in most other areas, gamification seems to work great in an educational setting. The services offered by companies such as Codecademy and Treehouse are incredible because they allow students to learn on their own schedule, select interesting topics from a wide range of available courses and be validated by celebrating many small victories along the way.
Unless traditional educational institutions can transfer some of that positive energy to their courses, programming is currently best learned through one of the aforementioned platforms. They are passionate about teaching people and strive to make and keep it fun.
If colleges cannot offer that, the vast majority of students is going to continue to fail their exams.