Why Functions Confuse Beginners (and the Fix)
A working theory of why one specific concept stalls more new programmers than the rest combined, plus four exercises that reliably fix it.
It Is Not About Syntax
I have taught intro programming for three years now. Of the 13 concepts on this site, the one that consistently breaks people's brains is functions. Variables click in 20 minutes. Loops in an hour. Conditionals are usually obvious. Then we hit functions and the room goes quiet.
What is strange is that the syntax is not hard. function name() { ... } is shorter than a for loop. So why is it so painful?
I have watched this happen with hundreds of students by now. The pattern is so consistent that I have stopped treating it as a coincidence. Something specific about functions as a concept is harder than the things around it. Here is my working theory after watching hundreds of students hit the same wall.
It Is a Shift in Agency
Up until functions, every concept is something the program does. Variables store. Loops repeat. Conditionals decide. Each is a noun the student can point at.
Functions are different. A function is something the student names and then summons. The student is no longer just reading a recipe; they are writing a sub-recipe and calling it from the main one. Two new things at once: definition and call.
Worse, the two pieces are physically separated in the file. A student writes function greet(name) at line 10 and greet("Aisha") at line 30. To follow the program, they have to mentally jump back and forth. Beginners have not yet built that mental jumping muscle. Their attention is still linear.
The Vending Machine Mental Model
The analogy that finally lands for most students is a vending machine. A function is a machine. greet("Aisha") is putting in a coin (the argument) and pressing a button. The machine produces a candy bar (the return value).
Once a student internalizes that, the rest of the syntax stops being mystifying. Parameters are the slot the coin goes into. Return is the slot the candy comes out of. The function body is the machinery inside that the student does not see.
The piece that is harder to explain than people admit is that the same function can be called many times with different inputs. Most beginner code reads the function definition once and assumes that is the program. They have to learn that defining a function is just the manufacturing step. Calling it is when work happens.
The Four Predictable Mistakes
- Defining a function but never calling it. Code does nothing. Student sees no output. Student panics. They wrote a function and the screen is blank.
- Calling the function but forgetting to print the result. Code runs invisibly. Student sees no output. Student panics again. The function returned a value but nothing displayed it.
- Returning
undefinedby forgettingreturn. Same outcome — invisible failure. Most language runtimes do not warn you that a function returned nothing. - Mistaking parameters for arguments and vice versa. Confused naming bleeds into confused thinking. "Parameter" is the placeholder; "argument" is the actual value. They are not the same word with two synonyms.
Each of these is small individually. Stacked together in a single program, they create the impression that nothing works for any reason — which is the worst possible learning environment for a beginner.
Four Exercises That Fix It
What worked in my classes — in this exact order:
- Type the same function 5 different times with 5 different names. Force the muscle memory of definition + call. The repetition is the point — students stop thinking about syntax and start thinking about purpose.
- Convert 10 lines of inline code into 5 small functions, each named for what it does. The student feels the cleanup happen in real time. Their previously messy script becomes a sequence of named verbs they can read like English.
- Return-only round. Every function returns a value, no printing inside. Student must
console.log(myFn())to see anything. This finally separates the two ideas: doing work versus showing work. - Functions calling functions. Build
area,perimeter, thendescribeShapethat uses both. Composition unlocks the lightbulb. The student realizes a function can be a building block for a bigger function.
I run these in pairs. One student types, the other reads aloud what is happening. The talking matters. Articulating the call/return dance forces both students to confront the parts they do not understand.
See It Animated
The function call-stack visualizer on the functions lesson is built specifically to make the call-and-return dance visible. Step through factorial(4) and you will see why recursion stops being mystical.
The visualizer also makes it concrete that each function call is its own little execution context. When a function calls another, the original is paused, not destroyed. When the inner one returns, the outer resumes from exactly where it stopped. Beginners struggle with that because they assume code runs strictly top to bottom — and functions are the first concept that breaks that assumption.
The Takeaway
If you are stuck on functions: it is not because you are bad at programming. It is because functions require a structural shift in how you read code, not just one more bit of syntax to memorize. Sit with the four exercises above for a week. Watch the visualizer. Read your own code aloud as if it were a recipe with named sub-steps.
The other side of this concept is where programming actually starts feeling like programming. Everything from React components to AWS Lambda handlers to your first 200-line script is functions calling functions. Past this hill, the rest of the language gets easier — not harder.
If you are teaching someone: do not skip the explicit definition-versus-call distinction. Do not assume the vending-machine analogy is obvious. Spend a session on it. The hour you invest there saves a week of confusion later.