(Previous: Engineering: Q&A)
Every teacher has pet peeves. Every programmer does too. This post touches on something that is on my teacher list AND my programmer list: impractical examples.
As part of my professional development, I watch a lot of tutorials. A lot. I want to get all the interesting background knowledge and CS fundamentals that college students studying programming get, plus stay up to date on current tools and frameworks.
And every few tutorials or so*, I come across an example like this:
Imagine you have a class called “Animal”. And your animal class has a speaking action: “Speak()”, and a movement action: “Move()”. And all future animal classes inherit from that class, so if you make an animal class “Duck” (inheriting from Animal), it inherits the functionality as well (i.e. you can call Duck.Speak() or Duck.Move()). But then . . . what if you want to make sure different animals speak differently? You might have variations of Speak() that depend on the animal: Bark(), Quack(), Moo(), etc., and overwrite Speak().**
The quacking ducks and barking dogs and swimming fish will all thank you profusely.
So will your frustrated students.
It’s not that I hate animal examples. I think they’re great, in the right context. It’s that animals are not digital, which means that their relationship to programming is fuzzy and arbitrary at best, and trying to force an example like this only works when you already understand the concept being explained. Animals are animals, we can’t control what they do by typing on a keyboard. And why is there a duck, or any other animal, in your program anyway–what does it do in the context of your program? These examples break down pretty quickly under scrutiny, and people who are reasonably good at logic (like aspiring programmers) are going to scrutinize everything you say, because they really want to understand.
While this kind of example drives me crazy, I also know (as a former teacher) that there is a strong pull to keep teaching things the way you were taught, and it seems obvious to me that a lot of people were taught this way.
So I’ll start with my easiest-to-implement suggestion: If you are into using these kinds of examples, and don’t want to redo all your lessons, stretch just a little further and make a VideoGameCharacter class (with a picture as example, see below), or a Robot class. These are computer-related examples, but you can still use animals with them, and they make much more sense.
So as in the above example, you could have an VideoGameCharacter class with a Speak() function and a Move() function, and make a duck VideoGameCharacter for a fake video game (and implement Quack() and Waddle() as variations of Move() and Speak()). Or you could have a Robot class (think electronic children’s toys) that has Speak() and Move() functions, and then make a duck robot that implements Move() with Waddle() if it has feet (or maybe Roll() if it has wheels), and Speak() with Quack() (or whatever crazy animatronic sound you have).
Or for another everyday example, if you want to stretch a little further: think of a “CalculateItemPrice()” function when you are checking out at the grocery store. Depending on what you are buying, the calculations might need to include weight (vegetables), total amount of that particular item (two-for-one-deals) and coupon codes, so you might have different implementations of how to calculate an item’s price, depending on what that item is.
You could also think of examples from apps and websites, which most people would know even if they’re not programmers. For instance, my library website has a “Check Out” button for electronic loans, but the check out function applies differently depending on what kind of content you are downloading (depending on the preferred format for Kindle, Nook, or other eReaders).
In my opinion, these would all make better “easy” examples, since they are examples that spring from the transformation of everyday items. When we have to think about how to calculate intuitively obvious things about everyday stuff–how that stuff moves, sounds, weighs, and/or how much it costs–that is when it also makes intuitive sense think about that stuff in terms of classes and inheritance.
I’m sure you can come up with other examples.
Why does this matter so much to me? Because for many people who are trying to get into programming but struggle with Impostor Syndrome, when they hear an “easy” explanation and don’t understand (it’s not hard to understand that a duck quacks, so why is building an inheritable Animal class sooooo confusing?), they think that they must be stupid. They don’t blame the teacher. They don’t say “that was a bad example.” They say “I guess maybe I don’t have what it takes to do this after all.” Seriously. And that is one of the ways that we lose talented people from the already very leaky software engineering pipeline.***
So please, please, please, can we stop programming ducks and dogs and fish and move on to programming things that can actually be programmed?
*Animal examples do get harder to find when you move into the harder concepts, though I did find one this week in a popular course that was talking about design patterns.
**One example had a Duck class that could Waddle() and Quack(). So you could have a Mallard class that inherits from Duck, and then call Mallard.Quack(). Fine. But then the example took a crazy turn with: what if you wanted to create a rubber duck and it doesn’t quack–it squeaks!–and it doesn’t waddle–it floats! Let’s change our structure! And all I could think was “why would you put a rubber duck in a Duck class at all? Wouldn’t you want a Toy class or something else at that point?” No offense intended to the instructors, who were (besides this example) quite easy to follow.
***Guess who is most affected by Impostor Syndrome? Women and minorities. It’s a complex issue, obviously, but when you’re already outnumbered (like in a lot of the tech world) it’s very easy to feel like you must be the problem when you don’t understand something. Realizing that the examples we use can make people feel stupid and excluded is an important first step in dealing with why certain groups of people give up on learning to program. Following through on that realization by changing our examples (and sometimes our teaching styles) to facilitate the “aha” moments of real understanding is absolutely crucial. Changing an example can mean plugging a leak in the pipeline.