Learning how to code was hard, you just forgot

Troy Leland Shields
Weave Lab
Published in
13 min readDec 21, 2018

I am pretty sure that on one single day everything just clicked into place for me, never to be unclicked. I had had so much frustration with compiler errors and unhelpful TAs and segmentation faults; in one magical moment it all dissolved away: the heavens cleared, the seas parted, and I walked leisurely towards a six-figure salary as a software developer.

This might be a bit of an exaggeration, but something rings true here for many developers, I think. In the beginning, we are doing one type of learning that is slow and arduous, then after some magical inflection point our learning changes to become fast and exciting.

We remember feeling utter confusion but we can no longer understand why. We forgot what it was like to not know, and we are therefore pretty bad at helping others who want to know. We’ve convinced ourselves that most software concepts are intuitively understood, and that everything else is easy to Google.

While many people do successfully teach themselves to become programmers (Weave has several), it is undeniable that there are some conceptual blockers that new developers will bump into early on in their studies. These blockers will turn many people away from software development before they even get a real chance to fall in love with it. Many of us have forgotten ever having to struggle over these hurdles, so we lack empathy when we just expect new students to Google it and figure it out.

My wife and I started a part-time dev bootcamp for women called Parallel Learning that meets in the evenings at Weave. Our goal is not to teach web-dev front-to-back so that students can go get high-paying jobs, our goal is build ramps over those hurdles that stop people from progressing on their own.

We could list a dozen hurdles and talk about ways in which we succeeded and failed to build ramps over them. Instead, however, we’ll dissect four examples we came across and how Parallel Learning tried to help our students overcome them.

The goal is to help communicate that even the most basic programming concepts have become easy because we learned it so long ago, not because they are inherently intuitive. This will hopefully help you have some empathy as you mentor others who are just starting out.

Variable Assignment

Below is a problem that we’re going to use to discuss the issues behind variable assignment. See if you can answer it.

int a = 10;
int b = 20;
a = b;
What is the value of a and b?

Honestly, at first it might be hard for you to imagine any possible way in which this is not intuitive. The answer is literally right in front of your eyes.

Perhaps you’ll feel the same way as this Reddit comment from a thread about the history of the assignment operator:

If you don’t understand that, you are not a functional human being. Your problem isn’t with a programming practice; it’s with your complete lack of intelligence.

— u/ConciselyVerbose, April 12th, 2018, 0 karma

The code above, while very simple, actually comes from a study that was trying to determine if there was a simple test that you could give to “laypeople” to determine if they would be successful programmers or not. The study had a dozen or so questions just like the one above. It claims that three groups of people emerge from this test:

  1. The group that gets it right.
  2. The group that gets it wrong, but gets it wrong consistently. They developed their own rules for the statements and followed those rules instead of the “correct” rules.
  3. The group that “just can’t” and gives up. They turn in empty sheets. Apparently this group constituted like 33% of the total test takers.

When I read that there was a group of people that couldn’t even guess an answer to these questions, I was flabbergasted. It’s so intuitive! a is 10; b is 20; a is 20. How can you just not answer that? At least take a guess!

I promptly printed the test out and gave it to whomever I happened to be with at the time. Sure enough, my brother-in-law, James, stared at the page for a few minutes, ultimately sighed about the question not making any sense, and handed me back an empty sheet.

Now, I can tell you for a fact that he does not have a “complete lack of intelligence” as u/ConciselyVerbose would suggest, so what’s going on here?

For one, there’s not a huge reason to have expected James to inherently know that these lines would be executing one after the other in descending order. He may have just assumed they are all true at the same time.

Second, he understood this as a math problem and therefore used the equality operator, not the assignment operator.

a equals 10; b equals 20; 10 equals 20

Wait, no it doesn’t.

Even if he had figured out that a variable could be reassigned with the = symbol, there is still nothing intuitive about assigning the right-hand side of the equation to the left-hand. That is completely and utterly arbitrary.

Teaching Variable Assignment

We believe that it is extremely important to teach about variables correctly because they are the first and simplest form of an abstraction. We teach this from the very beginning. A variable is an abstraction for a value.

Every student has to complete 10 pre-work assignments on their own before the first day of class. One of the very first of these assignments explicitly teaches about the difference between the equality and assignment operators by having them work through some simple math equations.

An excerpt from the variables pre-work assignment

Students are taught to read the “=” symbol as “is” or “gets” instead of “equals”. This helps break the notion that equality has anything to do with “=” in programming. That’s an entirely different operator: == .

Unfortunately, this is only the very beginning about what’s hard regarding variables. Variable declaration vs. assignment, data types, scope, etc. have just as many arbitrary rules that we think of as intuitive.

Control Flow

The flow of execution in a program does not come naturally to all students. We think that reading code is as simple as reading a book; top-to-bottom, left-to-right. Except sometimes you jump to this paragraph back in chapter 1 and sometimes you reread a paragraph 200 times and sometimes you skip three paragraphs entirely. At times you need to go open an Encyclopedia from the library and read that. Also this book starts at page 153.

A beginning student doesn’t yet have a concept of what a program looks like at the atomic level; the fact that a program is lines of text that are executed sequentially and represent specific instructions might be a brand new concept.

Why does it have to execute one line at a time? Why not write a bunch of instructions that all execute at the same time (more like CSS)? These are all fair questions for a new programmer, and it’s wrong for us to assume that it just makes sense.

Teaching Control Flow

At Parallel Learning we teach our students that they must learn to execute their program the same way a computer would, and in order to do that they must understand control flow.

We emphasize that a program can do one and only one thing at a time. We represent this by imagining a sing-along’s bouncing ball that bounces through a program, executing one line of code at a time. We teach them that the first step to reading code is to find out where the sing-along ball starts bouncing, and to follow it methodically from there.

It helps tremendously to have a very demonstrable example to illustrate control flow, such as this imaginary program for making a sandwich.

Once we’ve established this foundational knowledge that (1) order matters and (2) only one step executes at a time, and we’ve also provided a concrete way to talk about control flow (our sing-along ball), then teaching control-flow structures like if-statements, loops and even concurrency becomes a lot less daunting.

Functions

Oh boy functions. Go ask a recent boot camp graduate to call a function and pass parameters to it. There’s a pretty darn good chance they do this incorrectly. This isn’t because they are dumb, it’s because it’s not as intuitive as we think it is, and so it isn’t taught well!

Defining a new function is one new concept to grok. Calling a function is something else entirely. Calling a function with parameters is even separate from that. Returning values from a function is yet another layer of conceptual drama to work through. Don’t forget about the introduction of scope. And this is all before they really grasp what a variable is.

Even after learning the basic concepts, students still don’t understand the reason for writing a function until much later. It makes no sense at first. Why would they write part of their program in one place and then jump to a completely new place to write some other piece of it. No thanks, I’ll keep it all in one place where I can see it all in the correct order.

It’s hard to argue with that logic, especially for a toy app like the ones they are starting out with.

You’ll see some extremely creative syntax from new developers when they are trying to call a function. The fact that variables seem to jump around and get renamed really causes some confusion. (Parameters, for some reason, really throw new developers for a loop). While teaching our students, I saw many examples just like this one from u/Bitt-r on reddit:

The top comment: “Yeah that’s not even gonna come close to compiling.” — /u/grimmxsleeper

Teaching Functions

As part of students’ pre-work, we introduce the concept of “functions” into the fantasy PB&J program.

The steps to make a sandwich have not changed at all, we’ve just organized our code in a way that is more abstract and reduces duplication; it is therefore easier to read and maintain.

We teach that the sing-along ball “bounces into” a function when it is called and takes the input parameters with it as it goes. It bounces down the function as normal, and then “bounces back out”, bringing any return values with it.

We previously explained that a variable is an abstraction for a value, so now we introduce the concept that a function is an abstraction for some behavior. This is the second example of an abstraction our students come across before they have even installed Go on their machines.

Later on, in class, we build upon the concepts of functions by using the Turtle graphics mode on goplay.space. Students first draw a line with the Gopher, and then create a drawLine function. Then they use drawLine four times to create a rectangle; then they create a drawRectangle function. Eventually they get to a point where they have a drawHouse function and they use it to draw a neighborhood in main.

Each function tells a nice story, as if we’re reading a book.

The main function tells the story of a neighborhood: it’s a place with several houses. The drawHouse function tells the story about a house: it’s something made up of two rectangles and a triangle. The drawTriangle function tells the story of a triangle: it’s something with three lines.

At this point, we compare the code they’ve written to code that completes the same task but without helper functions. It becomes immediately clear that the main function tells a compelling story when using well-defined functions, whereas it’s an incomprehensible mess without them.

Furthermore, we have a very visual example of how parameters work. You can call drawRectangle with different colors and size params to draw the door and to draw the frame of the house.

Google-fu

Ah Google, the skeleton key that unlocks all knowledge for a programmer. What does it mean to be a programmer more than just Googling some stuff and copying and pasting whatever you find into a text editor?

Unfortunately, the thing we point to as the answer to all the hurdles that new programmers will face is often a hurdle unto itself, and I’d be remiss if we didn’t discuss it at least a little bit.

Let’s start with the simplest possible time a new programmer might need to Google something: they’ve just executed their program and it spit an error out at them.

While it might seem extremely obvious to you to immediately copy and paste that error into Google, a new programmer has no clue that this error exists outside the context of their laptop. They have no notion that thousands of other programmers, within the last week, have come across that same issue and solved it and shared their findings for free on the world-wide web. So they will sit there and stare at it instead.

That’s the easy case. The case where the answer to the question What should I Google? is presented on a silver platter. The far harder situation is when they aren’t sure what to Google at all. They aren’t even sure what they need to ask a human, let alone a computer.

Let’s say they do figure out what to Google though, sifting through the results is far less intuitive than we think it is. On more than one occasion I have been working with a student and decided to show them how easy it is to Google the answer for the issue they were having rather than just tell them, because I’m a rockstar teacher obviously.

It goes something like this:

I type in a well-crafted, specific yet succinct phrase into the search box. Within fractions of a second tens of thousands of results appear.

The next 20 seconds are a blur of mouse movements and hmming and hawing.

I quickly parse the top three results.

The first one is a tutorial blog post that I recognize might have the answer I’m looking for, but much deeper than I want to look; we can probably find it more directly. I open the second one, but the background color of the webpage for some reason tells me I’m not likely to find a relevant answer here, so I go back to Google. The third one is from StackOverflow so I probably should have just started here anyways.

I scroll past the question entirely and the accepted answer appears. I notice the one below it has far more upvotes though, so I keep scrolling to look at that one instead. Ah yes, we’ve found it. Within seconds I’ve copied the answer, pasted into their text editor, and their code magically works.

“Now, see how easy it is to Google your question?” I ask. The student has a befuddled look but says “thanks” and I’m back circling the room to do God’s work for someone else.

All I proved was how easy it was for me to Google the answer for their problem. Sifting through Google results is literally like explaining how a neural network makes a certain decision: it just does. They have no clue why I Googled what I did, or how I decided which results were relevant and which were not.

Once they do find the right web page from Google, however, then they are set, right? Wrong again, unfortunately. Whatever blog post or tutorial or Stack Overflow they happen to be reading is likely to be fraught with terminology they have never heard. They have no shelf on which to add new information. We are trying to help them build a shelf, but it’s not going to happen instantaneously.

We could tell them the age-old answer, “If you see something you don’t understand, just Google it.” And now they are in an endless loop of Googling things they don’t understand.

Teaching Google

Unfortunately, if we failed at anything in our first iteration of Parallel Learning’s dev school I would say it was going out of our way to give practical experience with Google.

I did learn a neat trick from a coworker of mine. We were mentoring a new developer who Slacked both of us a paragraph long question about something. My coworker responded and asked him to shorten the question.

The new developer responded with a couple of sentences, and my coworker asked him to make it even shorter. Eventually, he asked his question in 4–5 words, and my coworker responded, “Great, now put that into Google.” I thought it was hilarious, but entirely effective.

Outside of being intentionally unhelpful like a computer-science TA, we’ll need to find some more proactive ways to help students get practice with Google. A fellow developer at Weave suggested that teaching “the vocabulary of code” can help immensely here. This makes sense to me, as it helps them start with a small shelf of knowledge upon which they can build more.

We could go on and on about how using a CLI, learning Git, importing libraries, making network requests, etc. are all hurdles that turn people away before they get a real chance to fall in love with programming, but hopefully these few examples have proven my point.

Yes, it is an option to throw people into the deep-end with the attitude that if they can’t do it on their own then they aren’t worth having as developers anyways; or, we can do our part to give them their best opportunity to teach themselves. We can recognize that some of these concepts were probably difficult even for us at one point, and that it would have been easier if someone empathetic was guiding us.

Please clap.

--

--