Is a loop an example of abstraction?


#1

So I’m giving feedback to my students’ written responses from this practice PT and several of them wrote about loops as an example of abstraction because it makes code more efficient. Here’s an example:

“An abstraction would be the for loop that was used to make multiple sound waves in the program. A for loop runs the code that is within it until the variable, that was declared within the loop, does not fulfill the condition that is given in the parameters for the for loop. Using a for loop helped us reduce the amount of lines in the program because it ran the code without us having to copy and paste multiple times.”

This student seems to be responding to the fact that this loop helps ‘reduce the complexity’ of his code because he doesn’t have to ‘copy and paste multiple times’. I’ve been responding that this helps makes his code more efficient, but actually doesn’t address this complexity issue.

Thinking about the actual AP task - a loop isn’t an example of an abstraction, right? And when it asks about reducing complexity, the AP is looking for responses more aligned to how it helps organize/partition/group together lower-level code into something bigger, right?


#2

Yeah, calling a loop an example of abstraction is probably not right. Your response is good. Let me ramble here a few more thoughts that might help you (and your student(s))

  1. First, let’s just get this out of the way: for all practical purposes when it comes to the AP Performance Task “abstraction” means a “function”. So you are never wrong to point to some function you wrote, call that the abstraction, and explain what it does. (There are other things you might “abstract” but the easy one is always a function).

  2. There is a particular nuance to “reducing complexity” that is part of an abstraction that I think is missing from your student’s response – and that is about hiding unnecessary or complicated details. “Unnecessary” here means unnecessary for understanding what the code is doing.

  3. related - Another typical property of an abstraction is that it nicely “encapsulates” a solution to a problem, and presumably that solution can be re-used and applied to other larger problems or in other contexts without having to worry about the inner details. Once you have encapsulated a solution to a problem it’s specific details can be put out of mind, freeing your mind to solve more complex problems.

Here is an example – Take this code, something akin to your student’s loop, I assume.

for(var i=0; i<4; i++){
    moveForward(100);
    turnLeft(90);
}

In some sense this loop makes the code less complicated than it otherwise would be because without the loop you’d need many more lines. But as a reader of this code, to understand what it’s doing, I have to consider the details, I have reason about it, and mentally trace it out to figure out what it’s doing. Now if instead the line of code were:

drawSqaure(100);

I don’t even have to think it all to understand what this is trying to do. It reduces complexity because it hides details about exactly how the square is being drawn - really it doesn’t matter whether this function is implemented with a loop or not if what I care about is drawing a square - which makes it easier for me to reason about and furthermore to use the drawSquare behavior in other code that needs square-drawing.

drawSquare is a very small example, but when faced with programs or problems where the code is really complex and tough to reason about, bottling it up into a well-named function really helps. And also, loops usually complicate code because they are hard to reason about.

Here’s another example to prove my point. Imagine you’re reading along in some code and you come across this chunk that uses a loop. Try to figure out what it’s doing:

var newStr ="";
for(var i=0; i<str.length; i++){
    var ascii = str[i].charCodeAt(0);
    if(ascii >= 97 && ascii <= 122){
       ascii-=32;
    }
    newStr += String.fromCharCode(ascii);
}

Now what if instead, you were reading along in some code and found:

convertToUpperCase(str);

Even if I am an expert and can read the first code segment and figure out what it’s doing in 5 seconds - it’s NOT abstract. It’s a very concrete, explicit process for converting characters to upper case. It takes some amount of brain power to figure it out. Whereas, that same code encapsulated in a function convertToUpperCase it takes me no time to understand and I can use my brain for other things, like whatever larger task I need this case conversion for.

I think it’s fair to say with abstractions there is a bit of a you-know-it-when-you-see-it kind of thing that comes with experience and is hard for the new student to grok. And it’s hard to define because you can start to go down the rabbit’s hole with abstraction - let’s not forget that EVERYTHING we do on the computer is an abstraction in some sense - the whole machine is an abstraction. You’re seeing characters on the screen that are being represented by pulses of electricity behind the screen.

I hope this helps.


#3

In a non-computer explanation of abstraction, we talk about driving a car. We don’t need to know how the engine or gears work, we accept that they will do their job. I then get them to come up with other examples. I know it probably seems a bit simplistic, but I can then extrapolate on to code etc and they seem to get it easier.


#4

I really like using the car to help explain abstractions. Tapping into their life experiences is a great idea!


#5

For real life analogies pretty much anything that has a simple user interface to operate something that is mechanically or electronically complicated - car, elevator, tv, microwave, etc. - will work.

They are good for introducing the idea. But programming involves a bit more, so your explanation might eventually evolve to something like this:

One of the reasons you can operate a car without having to know how it mechanically works is because its purpose is very clear. The purpose of a car is to get you from point A to point B. Because you know that fact it makes it intuitive to operate because the abstractions presented to you map to the fundamental things you need to do to get from point A to point B safely - go, stop, turn.

Programming is a little different because it’s less intuitively clear what the fundamental purpose of a computer is. This makes it harder to apply or combine the abstractions because you don’t know where you’re going, so to speak. The fundamental purpose of a computer, by the way, is to process information, but what that information is and how it needs to be processed is an abstract undertaking in and of itself.

So programming is often about combining known abstractions or building your own to solve problems. In programming most abstractions are a procedure of some kind, and each procedure is intended to solve a single problem.

So back to a real world analogy:

Say that your problem is that you need to microwave some popcorn, but the only microwave in town is on the 10th floor of a building downtown. To solve this problem you decide to: drive your car downtown, get in an elevator up to the 10th floor, and use the microwave. Thus your procedure for microwaveThePopcorn involves combining your knowledge of using the abstractions that let you operate several single-purpose devices: your car, an elevator, a microwave.

Now in programming when you give this procedure a name like microwaveThePopcorn you can put out of sight and out of mind the complications you had to go through to solve it, and you can use it and treat it as though it’s also a single-purpose function. So microwaveThePopcorn can be used as a part of a solution to some other larger problem like: preparing to have friends over for a movie.

I hope that’s helpful.

Baker


#6

Hey Baker,

I noticed you ended both of your responses with ‘Hope this helps’.

FYI - I copy-and-pasted your first response verbatim and gave it as part of a larger piece of feedback to my students, then had us discuss how this idea of reducing complexity differed from the ones they gave in their written responses. The consensus was that this was incredibly helpful in clarifying what the prompt is looking for in responses and how to better organize their code. I’m on the next round of revisions for their responses and they’re exponentially better than the first round.

So - I can say with confidence that your response tangibly helped my students better understand the prompt and improve their writing. Thanks for the in-depth response.


#7

Ha ha! Great to hear! Thanks much. Glad it worked out.


#8

Grading a PT in which a student identifies a loop as an abstraction. I’m letting it slide grade-wise this time because I never mentioned the distinction and I myself was confused whether it should count. Your explanation was informative and I’ll make sure to bring it up with my students in the future so they understand better the concept of abstraction.