Chapter 2

Learning Computer Science

Subsections of Learning Computer Science


Now that you understand a bit of what computer science is as a discipline, we will turn our attention to how it is learned. Understanding the learning process is key to effective teaching, especially in how it is grounded in a domain (like computer science). Once you grasp how learning occurs:

  1. You will be more aware of what challenges your students are facing
  2. You will have a better grasp of how to support their learning
  3. You can better evaluate or develop pedagogically-grounded lessons for your teaching

As we go through this chapter, remember that computer science is all about solving problems with computers through programming and computational thinking.

Natural Born Programmers

There is a prevalent myth that some people are “natural born programmers” to whom programming comes easily. This is a dangerous idea, as in accepting it, you are also accepting anyone who struggles learning programming is not meant to be a programmer.


This idea is especially dangerous idea for a teacher, as accepting it will cause bias in how you interact with your students. Research has consistently shown that this kind of unconscious bias on part of teachers subtly but effectively influences students’ interest and effort in learning computer science. We’ll explore this and related issues more in a later chapter.

The truth is that in learning to program, we are learning to solve problems in a way that can be performed by a computing machine. As we discussed in the previous chapter, this must be expressed in a programming language that has a limited and specific set of operations it can carry out. It has no ability to interpret our intent - only the ability to carry out instructions exactly as written and only if these are written in a language it knows.

As a way of exploring these limitations, see how giving instructions to a “computational agent” goes for the Darnit family:

The point of this exercise is to understand the exactitude or precision with which programs must be written. But it also reveals just how different people are from computers. The simple truth is that to become good programmers, we must learn to write programs by developing an understanding of how the computers work, as well as how to express instructions in a form they can use.

The rest of this chapter is devoted to understanding that learning process.

Genetic Epistemology

You have probably heard of Constructivism , a theory that states as we learn we are ‘constructing’ a mental model through which we understand the world. The foundations of this philosophy arise from the work of Jean Piaget, a biologist and psychologist who performed some of the earliest studies on knowledge acquisition in children.

Of especial interest to us is his theory of genetic epistemology. Epistemology is the study of human knowledge, and genetic in this sense refers to origins i.e. the genesis, so his theory concerns how knowledge is created by humans.

Piaget’s genetic epistemology was inspired by studies he conducted of snails of the genus Lymnea native to the lakes of his home, Switzerland. He was able to establish that what had previously been considered different species of snails based on the shape of their shells were actually one species. He showed that when the snails of one lake were placed in a different lake, the way their shells grew changed to match those of the snails living in the second lake. In other words, the traits the snails displayed altered in response to their environment.

Examples of Lymnea Examples of Lymnea

Piaget suspected a similar mechanism was at work in human learning. He proposed that the human brain, much like the bodies of the snails, sought to exist in equilibrium with its environment. For the brain, this environment meant the ideas it was exposed to. He proposed two different mechanisms for learning, accommodation and assimilation, which related to how structures of knowledge were formed in the brain.

Assimilation referred to the process of adding new knowledge into existing mental structures. For example, once you know of and understand colors, you might encounter a new one - say periwinkle, which falls between blue and violet. Since you already know blue and violet, adding the knowledge of periwinkle is a straightforward task for the brain of assigning it to a slot between the two in the mental structure of ‘colors’.

In contrast, accommodation refers to the process by which knowledge for which you have no mental structures to represent are learned. This process involves building these mental structures, and is far more work. Modern cognitive science equates this process to the formation and reinforcement of new connections between neurons - a significant biological investment. Thus, triggering accommodation requires significant stimulus, in the form of wrestling with concepts that are currently beyond your grasp - a struggle that creates disequilibrium for your brain, eventually leading to it creating the new structure to accommodate the new knowledge.

This is the basis of the ’eureka’ moment, when a difficult concept has finally become clear. No doubt you have experienced this in a subject such as mathematics or programming, where a skill or idea you’ve been struggling with suddenly snaps into place, and becomes far easier to work with. This is also why your math and programming courses put so much emphasis on homework - this work helps create the disequilibrium you need to trigger accommodation.

This understanding of the process of knowledge acquisition and accommodation have some important implications, as well as tying into other theories of learning. Let’s look at those next.

Cognitive Load

The theory of cognitive load suggests that we can only hold five to nine pieces of novel information in our working memory at a time. This working memory is the information at the “tip of your mind.” Have you ever walked upstairs to get something and forgotten what it was by the time you got there? This is because it passed out of your working memory (likely to make room for something new that distracted you on the way).

If this is the case, how do we get anything done? We create mental structures that allow us to store multiple pieces of information in schemas, essentially, patterns of information that can help us work with it, as a schema populated with information is treated as a single chunk by working memory. These schemas can help us organize information and also automate behaviors.

Remember learning to drive a car? How you had to pay attention to so many things? What was on the road ahead of you, what was behind you, next to you. What your control panel was displaying? How fast you were going? What the speed limit was? Likely you found it difficult to keep all of that in focus - but as you developed schema to help with it, driving became much easier. Possibly to the point that sometimes you don’t even remember how you got to your destination!

Creating new schema is essentially what the process of accommodation is. And once those schemas exist, learning new information that maps to them is the process of assimilation. For example, once you’ve learned what mammals are and several examples of mammals, learning about a new one is mostly a process of determining how it compares to the ones you already know about.

Understanding cognitive load can help us teach better, because we can take steps to reduce the number of pieces of novel ideas our students need to grapple with until they can develop their schema. Building scaffolding into early lessons and then gradually removing it is a key strategy. Also, cognitive load can help us better understand the challenges faced by students with ADD - in this condition, the brain has trouble determining what information should be held in working memory, and often displaces it with other sensory information.


Carol Dweck is a researcher who has been developing a theory on Mindsets, which are individual beliefs we each possess about what we are capable of learning. She describes her research in the following Ted Talk:

Essentially, her work identifies two common mindsets - a fixed mindset, which suggests that you have an innate capacity for learning a subject that cannot be exceeded, or a growth mindset which suggests that with practice and effort, you can continue to learn.

These mindsets influence how we cope with the cognitive disequilibrium from Piaget’s Genetic Epistemology. Remember, this disequilibrium is necessary to trigger accommodation - the process of building new mental structures. But it is also uncomfortable and frustrating - we often describe it as “hitting a wall” or “banging my head against a problem.”

Students with a fixed mindset encountering this disequilibrium assume they’ve reached the limit of what they can learn in the field. As you might expect, they don’t see the point of continuing to try. Instead, they look for other ways to relieve the discomfort that the disequilibrium is creating. They may act out, withdraw from active participation, drop the course, or even engage in cheating.

In contrast, students with a growth mindset believe that with more effort, they can persevere and learn what they are struggling with. Thus, they continue to try. And in doing so, they will eventually resolve that disequilibrium by the process of accommodation - building those new mental structures that allow them to reason about programming and computational thinking in new ways.

With this in mind, fostering a growth mindset should always be a goal while we teach computer science. Also, be aware that our mindsets are discipline-specific: a student can have a growth mindset in one area (like science) and a fixed mindset in another (i.e. mathematics).

Zone of Proximal Development

Another theory that often is referenced with teaching and curriculum development is Lev Vigotsky ’s Zone of Proximal Development . This zone represents the distance between what a student can do unaided, what they can do with assistance, and what they are incapable of doing.

Zone of Proximal Development Zone of Proximal Development

As a student learns, the central zone (what the student can do) grows, reflecting the development of new cognitive structures in their mind that support the knowledge and skills they need to use.

As that central zone grows, the zone of proximal development is likewise pushed outward. From a genetic epistemology standpoint, this zone represents the “right” amount of challenge to create enough disequilibrium to trigger accommodation, but not so much to overwhelm the learner.

Keeping this zone in mind when developing or selecting curriculum materials is especially important - you don’t want your tasks to fall too far into the center zone (representing boring make-work), or in the outer zone (too challenging for the student to even know where to start). You want to keep the tasks firmly in the students’ zone of proximal development. We’ll discuss strategies for this in the next chapter. But before we do, we’ll return to Jean Piaget and some of his other theories.

Stage Theory

In addition to the mechanisms of accommodation and assimilation Jean Piaget outlined in his Genetic Epistemology theories, Piaget identified four stages children progress through as they learn to reason more abstractly. Those stages are:

  • Sensorimotor - where the learner uses their senses to interact with their surroundings. This is the hallmark of babies and toddlers who gaze wide-eyed at, touch, and taste the objects in their surroundings.
  • Preoperational - in this stage the learner begins to think symbolically, using words and pictures to represent objects and actions.
  • Concrete Operational - In this stage, the learner begins to think logically, but only about concrete events. Inductive logic - the ability to reason from specific information to a general principle also appears.
  • Formal Operational - This final stage marks the ability to grasp and work with abstractions, and is marked by hypothetico-deductive reasoning (i.e. formulating and testing hypotheses)

Neo-Piagetian Theory

While Piaget focused his study on children, many of the researchers who followed him also looked at how adults learn. Their findings suggest that all learners progress through the four stages with any new learning. That is, when you begin to learn a novel concept or skill, you are building the cognitive structures necessary to support it, and that your progress through this process corresponds to these four stages. Moreover, they have found that the divisions between stages are not rigid and clearly delineated; learners can exist in multiple stages at once (which they call the overlapping waves model).

The Overlapping Waves Model The Overlapping Waves Model

Neo-Piagetians have gone on to create domain-specific theories expounding on these ideas. We’ll take a look at one grounded in the discipline of programming next section.

Developmental Epistemology of Computer Programming

Among these neo-Piagetian researchers is a group including Raymond Lister and Donna M. Teague whom applied these theories to the learning of computer science, formulating a theory Lister calls The Developmental Epistemology of Computer Programming. This theory describes the traits of programmers at each of the stages of development. In particular, they use a student’s ability to trace code (explain line-by-line what it does) as a demarcation between stages.

Stage Traits
  • Cannot trace code with >= 50% accuracy
  • Dominant problem-solving strategy is trial and error
  • Can trace code with >= 50% accuracy
  • Traces without abstracting any meaning from the code
  • Cannot see relationships between lines of code
  • Struggles to make effective use of diagrammatic abstractions of code
  • Dominant problem-solving strategy is quasi-random code changes and copious trial runs
Concrete Operational
  • Dominant problem-solving strategy is hasty design, futile patching
  • Can establish purpose of code by working backwards from execution results
  • Tends to reduce levels of abstraction to make concepts more understandable
Formal Operational
  • Uses hypothetico-deductive reasoning
  • Reads code rather than traces to deduce purpose

These stages reflect the progress the learner is making through accommodation, creating the mental structures needed to reason about programming. An expert has developed these structures, which reflect patterns in how code is written - that is why an expert no longer traces code - they can see the patterns in the code and immediately grasp its action and purpose. In contrast, the novice must deduce the result of each line of code, put those understandings together, and then deduce what it is doing overall.

Writing a program is similar, the expert begins with a clear picture of the patterns she must employ, and focuses on fleshing those out, while a novice must create the program ‘from whole cloth’, reasoning out each step of the process. They are not yet capable of reasoning about the program they are writing in the abstract.

This also helps explain why learning to program can be so hard. Abstraction is considered a central tool in programming; we use abstractions constantly to simplify and make programs more understandable to other programmers. Consider a higher-level programing language, like C#. Each syntax element is an abstraction for a more complex machine-level process. The statement:

x += 2;

Stands in for machine instructions along the lines of:


Which are in turn, simplifications and abstractions of the actual process of adding the two binary values in register 1 and register 2.

What is interesting is we don’t really need to understand all of that complexity - we just need to understand enough to be able to write the programs we want to create effectively. We’ll talk about that next.

Notional Machines

Going back to the previous chapter, we discussed both computing hardware and programming languages. Remember, modern computers have very limited instruction sets. But a programming language can provide a single command that translates into a lot of individual instructions in machine code.

Thus, when writing programs, we need to have some knowledge of both. But the good news is we don’t need exhaustive knowledge - just enough to understand the programs we are writing. Computer scientists often call this combined functionality the notional machine, an idealized computer that represents the combination of features from the hardware and programming language that together establish how a program running on that machine will behave. In other words, it is a simplified model of how computation is carried out.

The concept of notional machines was originally developed to help teach computer science. But when we adopt a constuctivist standpoint, we can also argue that in learning to program, each student is actually constructing their own notional machine, which incorporates everything they understand about the hardware and programming language they are learning. This concept of an internalized notional machine is very helpful, as a student misconception is essentially a flaw in that internalized notional machine. Because of this misalignment between their internalized notional machine and the real notional machine, a program that they write may not behave as they expect it to.

The process of developing programming skill is therefore one of developing a robust and accurate internalized notional machine. The skills of computational thinking then use this internalized notional machine to determine how to solve problems, as well as create the programs to embody those solutions.


In this chapter, we explored theories of learning and how learning computer science fits into them. In particular, we saw that learning computer science and programming creates new structures in the mind corresponding to physical changes in the connections between brain neurons. Piaget’s genetic epistemology theory tells us the process of building these structures requires a certain amount of cognitive disequilibrium - grappling with the subject material and trying to make sense of it.

Carol Dweck’s theory of mindsets helps us understand how students respond to this disequilibrium. Ideally our students adopt a growth mindset which encourages them to continue to work at learning the material, eventually building those mental structures. Vigotksy’s zone of proximal development helps define how much disequilibrim we need to create, and provides some guidance on how to control that.

Pigaet’s stage theory, as elaborated in the developmental epistemology of programming, gives us a way to reason about where students’ development is. And the neo-Piagitian overlapping waves model helps us understand that development is specific to individual concepts within the domain. And finally, internalized notional machines are a way of understanding exactly what some of those mental structures our students are building are - a mental model of how the computer and programming language work together that helps them design and write programs.