A teacher, these days, is not supposed to be harsh and demeaning. Warm-and-fuzzy is the fashion of the day.
Sometimes, though, we should not pander. For example, to convince students that they have something to learn.
The human mind is flexible; when taught well, many people can learn many subjects. But there is one case of absolute impossibility: you cannot learn something if you think you already know it — and do not.
If you teach introductory programming today you will face this issue.
Some of the students in the auditorium on the first day of class have already written programs, sometimes substantial ones. My colleagues and I documented the phenomenon precisely [1] for our specific context, but the phenomenon occurs in various degree everywhere.
These students often know quite a bit, particularly about specific technologies; if they have worked on commercial Web sites, they may be more adept than their teacher at PHP or JavaScript. But usually they lack the foundation, the solid knowledge that will enable them to become real software engineers with system skills and the prospect of a successful high-level career. (Consider the difference between an electrician, however effective in his job, and an electrical engineer.) Many of these students understand their limitations, and are starting a university program precisely to remove them.
There will be some, however, who come with the attitude that they know programming — after all, they have programmed! — and have nothing to gain from a programming course.
For those, and possibly for the others, a jolt or two may be useful. Jolts in the sense of problems that are very simple to state but may not be so easy to solve, even for a smart-alec programmer. Even if the exercises do not immediately make you popular in the warm-and-fuzzy sense, they can be useful, in the first week or two of the course, to bring everyone to attention.
In this article and the next I will propose two such exercises, which I find particularly useful. (After the second article I will include a call for other suggestions from readers.)
Contrary to what you might expect, these exercises, particularly the first, do not specifically require "computational thinking" [2]. We all root for Jeannette Wing's slogan, but when dealing with students, particularly beginning students, I am mostly interested in their skills for just thinking. The computational bit I can teach. At least, I can teach it if they already possess logical reasoning abilities. As to professional software engineers, the most talented and successful ones in my experience do not generally distinguish themselves by particular computational skills but by their aptitude to analyze complex situations and tricky problems logically.
My first "jolt" exercise is indeed not computational but purely analytical. It is even anti-computational in the sense that the computational answer, which most people can produce easily, is the wrong answer. The requested answer is definitional.
The idea for this exercise comes from Edsger Dijkstra. I do not remember where I actually heard or read it (I could not immediately find it at the Dijkstra archive at UT Austin), but I am sure I got it from him. It is a very simple question to state: define alphabetical order. The exercise appears in my introductory programming textbook [3] and I have often used it in class.
Every literate person has an operational answer — computational thinking! — since we can all find a word in a dictionary. But that is not the answer to the question. I do not want a process (look at the first letters of both words, if one of them is before the other its word is before the other alphabetically, otherwise if they are the same etc.). I want a definition. I want the answer to be the completion of the following sentence:
A word x is alphabetically before a word y if and only if…
Replace the "…" by a proper condition on x and y.
To make sure that the problem statement is both clear and simple we can make the details precise: we restrict ourselves to words made of lower-case letters from the plain 26-letter Roman alphabet; letters are ordered ('a' precedes all the others, 'b' precedes all others except 'a' and so on).
I have found that many people — not just beginning students — have trouble coming up with a simple and correct definition, even though they have no difficulty applying the operational process — when asked to order two given words, or looking up a word in an alphabetical list, or giving examples of alphabetically ordered pairs of words.
Yet effective software engineers need precisely this kind of ability:
- High-level understanding of the concepts.
- Ability to reason definitionally and not just operationally.
- Ability to state a problem precisely (how many people, and not just in software, rush into a solution to the wrong problem?).
- Cogency, ability to explain what you do, documentation skills.
- Ability to abstract from individual examples to the general case.
Try this little exercise on your students and others (starting with yourself). I think you will find, like me, not only that it is illuminating but the right first step to writing a program to test for alphabetical order.
The second exercise will be very different: more programming-oriented at first sight, but also focused on analytical skills. Stay tuned.
References
[1] Bertrand Meyer: Knowledgeable Beginners, in Communications of the ACM, Vol. 55 No. 3, pages 10-11, available here. Based on report written with Michela Pedroni and Manuel Oriol, available here.
[2] Jeannette Wing: Computational Thinking, in Communications of the ACM, Volume 49 Issue 3, March 2006 , pages 33-5.
[3] Bertrand Meyer: Touch of Class: Learning to Program Well Using Objects and Contracts, Springer, 2009, book page here.
Join the Discussion (0)
Become a Member or Sign In to Post a Comment