This scheme takes a “functions first” approach to programming. All programs, even the simplest, are deconstructed into subprograms. There is no doubt that for many students this is a challenge, especially when it may require an understanding of parameter passing, variable scope and return values. However, this is largely because students aren’t introduced to these concepts early enough in a scheme of learning. Teachers have a perception these concepts are difficult for students to learn, but this is based on prior experience of introducing them much later in a scheme of learning.
Individually none of the principles are difficult. A program can be broken down into different subprograms (decomposition), those subprograms may require data for processing (parameters). They may also need their own temporary storage to carry out the processing (local variables) and the results are returned to where the function was called. Thereby extending the functionality of the programming language with user-defined functions (reusable components).
A problem arises because students become so used to writing code without subprograms in the early part of their coding journey that they don’t see the merits of the approach and it becomes extremely hard to break established habits later. In the same way that teachers encourage students to use comments and sensible identifier names from the start, so too then teachers should insist on the use of subprograms as well. The more that students use subprograms, the more they become comfortable with them and just see it as the way programming is done.
Teaching with a “functions first” approach is not new and has been suggested for some time. It has been very evident in our own classrooms that it makes a significant difference to student’s understanding of programming at all ability levels. Richard Pawson was one of the early proponents of the approach, writing an article in “Hello World” magazine issue 7.
In his article he suggests going much further by adopting the practices of functional programming where the inputs, processes and outputs are completely divided into their own subprograms so that only input functions collect input, and this is passed to processing functions. This scheme takes a pragmatic approach instead by adopting the spirit of “functions first” without insisting on the stricter requirements of functional programming.
It is frequently quoted that subprograms are too hard for students, which is the main argument used for introducing them later, but consider this line of code that students are often introduced to very early on:
choice = int(input(“Enter a number”))
Teachers don’t consider this difficult to understand because students are introduced to this as the way an input is collected from the user. In reality, it is far from straightforward. The output variable is on the left, compared to being on the right in maths. The input is a string so must be cast to an integer data type. Arguments are enclosed in parenthesis, and strings are qualified with quotes. There is nothing simple to understand here at all! So subprograms are no more difficult to understand either, and in fact, make understanding what is happening with a variable, casting and input in this statement much easier to understand too. The problem is that it takes years before new and better ideas become the norm in teaching. Too frequently teachers teach how they were taught.
The solution is to introduce students to subprograms in small steps, one concept at a time and not all at once.
This scheme teaches this concept first:
In later programs students learn that:
The best practice uses different identifier names for arguments (data passed into a subprogram when it is called) and parameters (variables receiving data by a subprogram). This ensures there is no confusion between the scope of the variables. However, this has proven to be a significant barrier for many students, so this scheme takes a pragmatic approach of having the same identifier for both arguments and parameters. While this is not best practice it does help students understand that the argument and the parameter are the same value (even though they are different variables with a different scope).
For most students this compromise is worthwhile, using subprograms for problem decomposition and reusable components. For stronger students there is an opportunity to discuss scope, local and global variables.
Although teaching subprograms from the very first program is a good idea, this scheme scaffolds the experience for students. The learning programs have the function definitions and calls already coded for the students. The one- and two-star programs also include function definitions and main program calls. It is only the three-star programs that require students to write the code for function definitions. This provides a lot of support for students so they can identify how and why subprograms are used, but can concentrate their effort on the code inside the routines instead.