# How can I help students develop intuition about a programming language?

As an tutor for introductory CS classes, I often come across students that have a very rigid understanding of a programming language up to what they have been taught so far. This most often manifests itself when they ask the question "I can do that? I thought that...". I've most often seen this when showing students that branching and looping statements can be nested. It has even occurred when dealing with parenthesis and order of operations in mathematical expressions. As a concrete example, in Python many containers allow access via brackets:

# dictionaries
foo = dict()
foo["a"] = 10
foo["a"]
# deques
bar = deque('asdf')
bar[0]
# and many more...


These students usually repeatedly struggle with this every time a new construct is introduced, as they fail to see how certain concepts from one part of the language extend to the other parts. In this case, it is that brackets are used for accessing elements.

In short, how can I influence the student's thinking process from "This language only allows me to do this" into "Can this language do this?", and help them expand upon what they have already seen and understood?

I think this is a structure of knowledge problem. I suspect the disconnect is that you have organized your knowledge in a way your students haven't.

You understand that strings, lists, dicts, and deques are all something called containers. You also understand that all containers can be accessed with []. Therefore, it's straightforward to consider that [] could be applied to any new container you come across.

But do your students understand this organization of types in terms of containers? I bet they don't yet. They are still thinking about each type as an individual entity, disconnected from others.

Experts' knowledge is organized much more effectively than novices'—— that's what it means to be an expert. (Cite: Relevant section from How People Learn, summary from Cal State Northridge)

On the other hand, novices' understanding is tightly tied to shallow features like syntax. It will take a while for them to see the deeper organizational features.

You can help your students become more like experts by explicitly helping them organize their knowledge. If it's not overwhelming for the students, teach them what a container is and what all containers have in common. More generally, connect concepts together to help support students' development of those expert-level connections.

Good luck!

• @nocomprende Awesome! Learning Science is pretty great :) – nova Jul 19 '17 at 16:18

If the student is asking such questions, then we're already off to a great start. You have meta-cognitive learners!

Now, I must caution you to be reasonable about your expectations. You write that "these students usually repeatedly struggle with this every time a new construct is introduced, as they fail to see how certain concepts from one part of the language extend to the other parts." This is perfectly normal. For students who don't naturally think as programmers, there is no magic bullet that will prevent us from having to expound on new data types. That is what teaching is.

What we can do is make sure that the understandings that students develop now are rich enough that they can at least be useful later.

I would suggest that you are asking how to get students roughly to levels 3-4 on Webb's Depth of Knowledge.

If that is the care, then you must first make sure that your students are comfortable in their level 1 and level 2 knowledge. A question like, "can we do that?" is a level 1 question. The students must see the forms, and they must be able to reproduce the forms. That means exposure (which is possibly what you were trying to get away from?) to many uses and contexts for the data structure or algorithm.

Level 2 involves comparing and contrasting, summarizing, predicting, and describing. We often learn levels 1 and 2 simultaneously. However, just because students often learn these together does not mean that we as teachers are free to avoid teaching both. We cannot assume knowledge from a student until we have tested it. In a tutoring session, that can be very informal, but we do need to make sure that level 2 is really intact if we are to make reasonable headway into level 3.

Level 3 (quote here) "requires deep understanding exhibited through planning, using evidence, and more demanding cognitive reasoning".

Ask your students to analyze and compare two different approaches. Ask them to solve larger, multi-step problems. Check in for understanding on every part of the problem. Ask them to generalize, explain the structure, and connect these ideas to other ideas, either from other data structures, or from other fields entirely. This last part is especially important; drawing connections between this information and older information (particularly from other fields) creates a rich intellectual landscape from which students may draw in the future.

I'm sorry that there is no magic bullet, but hopefully this should bring the students the fluidity you desire.

Well, my first thought is an analogy. Lots of things follow patterns, right?

English is a massive, complicated, crazy language, that often disobeys its own rules. (Python is much nicer.) But it, like most languages, has certain patterns. Like tenses, for instance - I drank some milk earlier tonight, but I'll drink some water tomorrow, and I'm drinking juice right now. There's other patterns, too - we don't often use 'methinks', but 'I think', or while texting, abbreviating words quite a bit as in 'lol' or 'ttyl'. We often prefer to use first person when talking, but second person in commercials, and a mix of third and first person in books. Roots in words can help you figure out the word's meaning.

In math, most operations have an inverse (subtraction and addition, multiplication and division, multiplying a matrix by a matrix and multiplying an inverse of a matrix by a matrix, etc). Operations involving apples and objects tend to involve integers, while bank accounts use numbers that can be represented as a ratio. Formulas involving circles tend to include $\pi$.

In physics, quantum mechanics involves more linear algebra, and it all uses calculus. Papers in physics tend to be more theoretical or more experimental, and experimental ones must show the statistical significance of their results. Physicists tend to be either theoretical or experimental, not both (a famous example being Pauli's ability to break experiments).

In Python, brackets with an index or value are used to access elements of a variable commonly, things can often be shortened to make them cleaner and more efficient. Readability and indentation is a must.

We use these patterns to jump to conclusions all the time - figuring out words from roots and context, parsing out the pronunciation of a word using phonics, guessing at the meaning of a particular symbol in math, generalizing results, and extending them. Python is no different. Picking out patterns and generalizing is right quite often, and is faster than painstaking trial and error, or reading through every word of documentation.

My second thought is pointed exercises. Have them access variables in a dictionary in a myriad of exercises. After quite a few exercises have them access a part of a string. They'll probably unthinkingly do brackets - and it won't break. Be nearby so you can point this out. Do more exercises with different variable types and point out the connection each time. Do this with other things besides the brackets. Ask questions like, "Where is this syntax familiar from?" or "Have you seen this technique before?" or "Does this look familiar?". Eventually, they'll catch on. Have them do something completely different (like nesting loops, etc) and watch while it doesn't break. Encourage them to experiment.

One of the issues with new students is that they are likely to think at a very concrete level. To program effectively, just as to be good at math, students need to be able to understand and form abstractions. In other words the students need to start to think at a higher level so that the concrete detail can be largely ignored most of the time. But this only works if the abstractions are accurate and compose-able. So to follow up on the answer of user @nova let me suggest that using analogy and/or metaphor is a useful way to do this.

In the specific case you mention (access to members of a collection) you can use your classroom itself as the collection and the names of the students as keys. Or, for arrays and such like you can "number the seats" and refer to "the student in seat 5" for example.

Building nested structures is another thing you mentioned. Russian Nesting Dolls (Matryoshka) can be useful for this. Structures inside structures. A box full of boxes can be imagined. An "if" box inside a "while" box, for example. You could use a physical analogy, a projected image, or just "imagine a box full of other boxes that may contain yet more boxes." Lots of things so that the student gets a mental picture without looking at the concrete details of code.

But, I'm guessing that you have mental pictures for most of the things you are trying to teach. Figure out a way to share them. Even more powerful is to suggest some metaphor or mental image and then ask the students for something similar in their "Own Words" (A Pedagogical Pattern). In hearing the answer you can get an idea of their level of comprehension and correct it or move on.