Introducing…. Mike’s Axioms for Computing Instruction.
As I do more and more teaching and lesson writing, I’ve started collecting the gemmiest of my design principles.
Little by little I’ll record them here in the blog with some examples and the reasoning behind them, and hopefully they’ll be a useful reference for me and others. As I deepen my formal knowledge and gain more hours of practical experience, I’ll come back and elaborate or revisit.
Here are some to get started, just placeholders for now:
- Remove artifice. Make exercises as close to “real code” in a “real building scenario” as you can.
- Teach only what’s necessary for students to know *right now*. (this might be the teaching equivalent of the YAGNI principle in agile software development)
- Minimize overhead. (Where possible, pick languages that lend themselves to this)
- Maximize time spent on hands-on tinkering, sometimes at the expense of lecturing.
- Teach *what it’s like to be a coder* or creator, not just how to complete the exercises. The process and self-conception are as important as the acquired skill.
- Demonstrate mistakes and other kinds of everyday programmer fallibility. Be open about acknowledging your limitations, copying and learning from others, and reliance on references. Do these unintentionally and ad-libbed, where possible.
- Have students do the next smallest thing that will work. Test, debug, move on. (Another concept that crosses over nicely from agile software development.)
- Use pseudocode & comments liberally for teaching.
- Follow the model: Read > Write > Create. Start with reading or watching to understand. Move on to editing or tinkering with or tweaking existing code to see what effect that has. Finally let students master the given command or technique by building their own.
I’ll leave it at that for now… Got any of your own to share? Leave a Comment!
Great start! Suggestion: Make the list an ordered one by replacing with in line 145 and with in line 155. This will make it easier for readers to reference axioms by their number when commenting. Thanks in advance!
Oops. I used literal HTML tags in the above comment. What was meant was replacing “ul” with “ol” and “/ul” with “/ol” in lines 145 and 155, respectively.
Great idea, Guy, thanks. I hesitate to number them this early; I picture tweaking the list as I learn more and get feedback, adding more items, and maybe combining or eliminating others. Bring on your comments; address them by the heading phrase and we’ll know which ones you mean.
Why the hesitation to number early, if I may ask? Changing to an ordered list doesn’t preclude you from combining some items, adding or deleting other “li” entries, etc. The renumbering will occur automatically, correct?
I concur with all nine existing axioms and am especially fond of “Teach *what it’s like to be a coder* or creator” and the elaboration on it. I’ve never read anything like this and it has deep ramifications. For one thing, it makes thinking computationally an experiential process involving the whole person as you aptly qualify as a creator. This is similar to my use of “codist” to evoke the “artist.”
Mike, I’m submitting the addition of a postulate for your consideration. Its drawback is that it’s not applicable to a total beginner:
When you have found a good solution to the challenge at hand and have written and tested your code, look for a better solution, e.g., more elegant. However, be mindful that “better is the enemy of good.” Thus, know when to stop and move on to the next challenge.
If you phrase that as “Coach them: First, get it to work. Then see if you can figure out a better (smoother, simpler, more efficient, more elegant) way to do it.” then I could get behind that, even for beginners.
It validates that tinkering and brute force are perfectly good ways to take a first shot at any challenge–but that there are often better solutions, and it’s worth trying to reach them. Those can be conceptual leaps that unlock new “levels.”
It might even be a good idea to structure programming lessons in such a way that kids are clearly pushed up against the limitations of the simpler methods they know, paving the way for the “aha!” moment when the more powerful method is introduced. Ex: get them to repeat a basic step 3 times, then 5 times, then 20 times (oh my god! the typing/clicking/dragging! there must be a better way!) before introducing loops. Maybe even hold out as long as you can until someone *asks* if there’s such a thing as a repeater or loop.
I wonder if there’s something like this in Mathematics teaching that we could borrow. Good suggestion!
Excellent suggestion! I especially like the way you guided (goaded?) students into coming up with asking about the existence of a “repeater” mechanism ( counted loop) by themselves and that this “aha!” moment can be induced very early on with complete beginners. Perfect! And, yes, my postulate should be rephrased as you mentioned rather than my initial version which was taken from chess!
YAGRI: You Ain’t Gonna Reuse it. Obviously modeled after “YAGNI: You Ain’t Gonna Reuse It.” Let’s be honest; for all the hype about code re-usability, it seldom happens (if at all) in the real world. Expending time to make part of your code so that it can be re-used is futile and thus a waste.
EDIT: The previous comment should have read:
YAGRI: You Ain’t Gonna Re-use it. Obviously modeled after “YAGNI: You Ain’t Gonna Need It.” Let’s be honest; for all the hype about code re-usability, it seldom happens (if at all) in the real world. Expending time to make part(s) of your code so that it/they can be re-used is futile and thus a waste.
Make your code free of side effects. This principle has at least two areas where it should be applied:
1. Within your program, avoid using global variables and have portions of your program modifying their values unless absolutely necessary. Get a firm grasp of variable scoping too.
2. If your program has external dependencies such as function libraries, import them or a subset of their functionsand deliver a stand-alone application with the libraries’ content “frozen” and embedded in your executable code.
Exception handling: Don’t do it!Having forgotten that Mike’s list of “axioms” was aimed at providing guiding principles for teaching computer programming to beginners, I went overboard with the two previous postings. My apologies.
Since the audience is people starting to learn to write code, they might not be familiar with the word “exception” which means “error” (and, more specifically, a run-time error).
Intermediate-level “codists” will deem my suggested axiom to be ill-advised — and correctly so.
However, for newcomers, it is best to let the programming language they use take care of all [unhandled] exceptions, no matter how deeply nested they might be, percolate up and result in an error message. Most modern languages will also include a traceback list of where the error occurred and how it was propagated to the top-level code.
The rationale is that a novice who has been (unfortunately, prematurely) taught to guard against unhandled exceptions by writing handlers for them (all?) may well fail at writing code that properly handles the exception(s).
When this happens, the exception is no longer unhandled and thus is no longer seen by the program interpreter/compiler as being an exception. Any faulty handling will prevent the language from generating a helpful error message and the program will fail with no explanation provided as to what exactly caused it to fail.
Thus, when starting to learn how to code, I deem it desirable on the part of the instructor to not even mention “exception handling.” This way, the numerous errors that the beginner is bound to make will always result in informative error messages.
Learning to read error messages (hopefully containing some traceback information) is also a useful skill to acquire to facilitate debugging.