Friday, March 30, 2018

Teaching abstraction to high school students

I have often found Abstraction a difficult concept to explain in high school computing classes. I now think that I found a few good examples to illustrate this concept and this post is about one of them.
First, let's define the word:
Abstraction ... is the process of taking away or removing characteristics from something in order to reduce it to a set of essential characteristics. (Abstraction on
In other words, we hide some detail so we can concentrate on the essential features of the problem at hand. Below, I will attempt to illustrate with an example which is implemented in Snap!, a block-based language created at the University of California, Berkeley.

The problem

Say, for instance, we wanted to draw this brick wall:
Brickwall activity from Beauty and Joy of Computing, UC Berkeley

Motivating abstraction, thinking in tedious detail!

Thinking at a low, unhelpful, level of abstraction, we could say:
To draw the above brickwall:
  • set the colour and thickness of the brush
  • advance the brush 40 steps forward
  • Lift the brush
  • Advance 5 steps forward
  • etc .. 
The instructions above only draw one brick and leave a gap in preparation for the next one.
Wouldn't be wonderful to be able to think in terms of "rows of bricks"?

Hiding detail, thinking in problem-specific language

I would much rather describe my solution in these terms:
- We have two kinds of rows of bricks:
  • A row A consisting of 6 bricks of length 30 units and a gap of 10 units between them:
  • A row B consisting of 5 full bricks and two smaller ones at the edges:
Now our brick wall consists of 8 rows of bricks, with alternating rows A and B (we can choose which we want to start with but my example above begins with a row B at the bottom).

Building the wall

To be afforded the luxury of thinking in terms like "row of bricks", we need to extend the language that we're using: We need to define "draw a brick" once and use it in the rest of our program. Here is what this definition looks like in Snap!

Having defined the drawing of a brick, we now have access to a block we can use any time we need to draw one:

Now we can define draw_row_A which simply draws six bricks with a space (movement while pen is up) between them.

And now we can simply "say" draw_row_A and specify the position like so:

Similarly, we can create a block that draws row B, taking into account that it has one extra gap. The "half bricks" are actually 17.5 steps long rather than 20, as might be expected at first.

Building the wall

Now that we have the language to do it, we need a block that does the following:


Let's get more abstract!

The solution above, which I admittedly didn't describe in detail, is good for building a brick wall with 8 layers, a specific size for bricks and gaps. The last task should be to build a solution that can draw bricks of any length with gaps of a given size. This allows us to solve the same problem for a larger set of requirements, which is another meaning of the word abstraction.

One difficulty is in adjusting the length of the small bricks on either side of row B:
At previous level of abstraction:

At higher level of abstraction:
We now need to realise that the small bricks have as length half the length of a brick less half the length of a gap!