How would I teach computer science if I didn’t have any computers?
What started out as a thought about how to teach recursion and scope has developed into a possible design for an introductory computer science course that wouldn’t include a computer. Those not familiar with computer science will find this more odd than those who are; but computer science has little to do with the machines we now call computers.
Computer science is the art of expressing injunctions in a formal manner. Formal means that the entire meaning of a statement is contained within the form of the statement, but that level of technicality is not really important; I would be surprised if most practicing computer scientists have even what formal means. What is important is to train computer scientists I might explain that computers see the form where humans see the substance behind it, but I doubt that that statement would help students. to turn off the very skill that makes human interaction functional: the ability to hear what is meant instead of what is actually said.
That is not something I know how to teach directly.
So instead I’d teach meticulousness. I’d give the students a paper version of a stack frame. I’d give them very explicit instructions about where to write what on the paper to perform basic computations. Then I’d introduce code as a succinct expression of those instructions, but continue to require them to meticulously follow every step.
At some point students will realize they can get away with skipping steps that don’t show up in what gets turned in. Before they get sloppy, I’d teach them to group steps, to generalize in controlled ways.
That would probably be a good time to introduce how digital computers work. I’d explain that, just as they can work at a higher level they can also work at a lower level, where all operations are made out of and, or, and not. “Programming” is the process of describing the abstractions that bring us from that boolean layer up to higher-level ideas. “Computer science” is the field that studies all of the elements of programming, including the design and analysis of these high-level abstractions.
This is also when I’d introduce the notion of procedures, though at a high level for starters. I’d talk about writing and invoking procedures separately, introducing them as a way of formally adding a new level of abstraction to the code, using example functions that the students can evaluate mentally to avoid speaking about the stack right at first.
Once procedures exist, it is natural to add a process for handling method calls. Not all languages have full block-level scoping; functional languages often don’t, nor do some scripting languages (notably PHP and Python) However, in any language with block-level scoping I’d first introduce scoping.
All along the students have been computing on three-column paper: type, name, and value. I’d probably also have given them paper for re-writing evaluation of complicated expressions, the human parallel to the register file. I’d explain that a block adds a sheet of paper below the existing sheet. Both are visible, so both may be referenced, but with the closing brace the bottom sheet is discarded.
This presented, it now becomes a simple matter to explain that a method invocation places it’s block’s scope on top of the existing scope, blocking view of the existing variables. Add in proper discussion of arguments and return values and methods, recursion, and the like are pretty straight-forward.
Perhaps this ought to be an earlier phase. It is not dependent on phase 3. The other big idea to communicate is the idea of allocating memory on the heap, which in most instances means creating custom data types. My idea here is to provide a set of numbered index cards and a master list of datatypes. The master list describes how to set up a card to store the right information; the number of the card is then used in place of its address.
There is certainly room to do this differently. I thought about providing a grid of cubbyholes to store objects in and using the address of the hole as the address, but I think the numbered cards will work fine. There’s also the question of what the master list looks like, if we make following it part of the stack behavior or not, if we include methods and object-orientation or not, etc. But the general idea remains.
The outline above could teach every principal taught in a typical CS1 course without ever turning on a computer at all. An up-side of that is it prevents relying on guess-work to replace understanding. Conversely, it makes it difficult to provide interesting examples and the kind of engagement that is currently believed to contribute to student interest in the field. If I were to try it out in the classroom (which I would still like to do) I would probably start using computers sometime in the middle of the outlined sequence, and then continue using them for weeks after completing the outline.