Once upon a time, nearly twenty years ago, Pascal was the most commonly taught language in high school and colleges. It replaced older languages like Fortran and more obscure languages.
I haven’t programmed in Pascal in quite a while, so you’ll have to forgive me if my recollection is a bit rusty. Pascal is a procedural language. There was no notion of objects with Pascal. In that sense, it resembled C.
Pascal had a few features that C didn’t have and vice versa. For example, in Pascal, there are two ways to pass a value to a function. Either you pass by value (a copy of the value is made) or you pass by reference (essentially, a pointer to the value is sent). Passing by reference in Pascal is similar to C++.
C exposes pointers everywhere. You can take the address of practically anything in C. In Pascal, you can only use “new” (or whatever the equivalent was in Pascal) to create dynamically allocated structures. You couldn’t take the address of anything.
Pascal allowed for functions nested inside other functions. If function Inside was nested inside of function Outside, then Inside has access to Outside’s parameters. Only Outside could make calls to the nested functions. They were not accessible by functions outside of Outside.
Pascal makes a distinction between a procedure and a function. In C, a procedure would be called a void function, i.e., a function that does not return a value. A function returns a value.
In C, for a function to return a value, you use the return statement, and return the value back with it. In Pascal, there’s a special variable named after the function, having the return type of the function. You assign this special variable to the return value. Unlike C, where the code of the function is complete once the return statement is run, Pascal runs the code until the end of the function block, even if you have already assigned the function variable.
To illustrate, suppose you have a function foo. This function is supposed to return an integer value. At some point, you’d be expected to assign the variable foo inside the function to an integer. In principle, you could assign it several times. Whatever value the variable has when the function block is complete, that’s the return value of the function.
Pascal was designed by Niklaus Wirth to be a teaching language, not meant to be used in the “real world”. Perhaps its chief deficiency is the lack of separate compilation (though later versions may have fixed that). This meant everything had to be in one file. I suppose it may have had a limited library (thus stabilizing the language).
In fact, the key feature of a teaching language is one that doesn’t change because industry demands this feature or that.
But let me not delve too deeply into Pascal. What I want to get at is what we think programming is.
When I was teaching programming, we spent a good deal of time talking about control flow, arrays, variables, functions, and pointers (we taught C). Notice one topic I didn’t cover deeply, and the one that might be of greatest controversy is algorithms.
Why didn’t we cover (much) algorithms? I was teaching at a public university in a major that was non-selective. Anyone could be a computer science major. And, unlike engineers, these majors require far less math to graduate. We required two semesters of calculus (or was it three?), a semester of stats, and a semester of linear algebra. Even so, all you need is a grade of C to pass, and that isn’t a particularly high standard (to be fair, there are excellent programmers that are awful at math).
Algorithms require some mathematical maturity to properly understand them. Many Ph.Ds have been so good at math for so long that they can sometimes scarcely believe that some folks are bad at it, or that those that are bad at it would even contemplate majoring in computer science. Yet, many students can become good programmers without math (I personally believe you can’t be great without some knowledge of math, however).
Some intro teachers focus on problem solving and algorithms rather than features of the language, believing that this transcends specific details of programming languages. In other words, you simply have to think algorithmically, not in any particular language (though resembling Pascal, perhaps). The niggling details of this language or that is merely a distraction, preventing you from solving a problem.
This is why many a professor has stopped programming for real. Those details are a pain. And why bother commiting them to memory. The proof for the undecidability of the halting problem is so much more elegant than the mundane overloading of the term static in C/C++, which can mean “having file scope”, “having static storage”, “being a class variable”, depending on where this keyword is applied, or remembering that a compare operator doesn’t always return -1, 0, 1 (instead returning negative, zero, and positive). After all, there are no syntax errors in proofs. You can write in stylized Math English, and have a great deal of latitude in the proof.
Still, these represent the two competing (possibly among many) ideas in teaching programming. In the one camp, which is the majority, teachers say syntax is irrelevant. The details of the syntax can be looked up, so look them up when needed. On the other, syntax is very important, because how many people are really going to look things up (not many, in my experience), but then syntax is often the first thing students forget.
Let’s compare this to English writing. Many a English teacher are grammar sticklers. There is a right way to write. There is a wrong way. Bad grammar is seen as an offense to man and God. However, more recently, some have advocated getting students to get their ideas across coherently, regardless of grammar. Getting students to write is more important than the niggling details of the language.
There is something to be said about this approach. Grammar is difficult to master. I recall a professor, who wanted to become chair of the EE department, who complained about foreign students and their lack of good English. He felt foreign students needed to be good at English (even as many native speakers are bad at it). I would guess that he had no good idea how to teach good English, nor how hard it is to master. I’d have more respect (but only barely), if he’d attempt to learn the grammar of another language (preferably Asian), and see just how challenging it is. Naturally, this person assumed that someone else (the student) would take care of this problem. If they had truly cared for foreign students to get good at grammar, they might have either hired someone to help out, or simply make acceptance into the program based on grammar.
The point is that English teachers used to stress the importance of grammar, but computer programming teachers somehow dislike this aspect of programming. And I think, as onerous as syntax is, it insulates students from real world programming.
The question of this essay is to ask what is programming, because once we have a semblance of answer to this question, we can then ask, how do we best teach programming? How do newcomers to programming fail to understand the ideas of programming? How is one beginner different from another?
In hindsight, when I was teaching programming, I stressed syntax. Occasionally, I discussed problem solving, but honestly, not that much. That was a mistake. I needed to strike a balance between the two. Indeed, even if a student never learns how to program “properly”, learning to solve problems in an algorithmic way is still of value.