result ← doubleIt(5): arguments flow into parameters, RETURN sends a value back — and RETURN exits immediatelyYou already use procedural abstraction daily. When you tell a friend "text me the address," you don't specify: unlock phone, open messages, find our thread, type, hit send. You name the task; they handle the steps.
Code works the same way:
DISPLAY (LENGTH(scores))
You've been calling LENGTH for six lessons without once wondering how it counts elements. Somebody wrote those steps; you use the name. That's a procedure: named code you invoke without re-reading its insides.
Today you move from calling other people's procedures to writing your own — which happens to be the exact skill the Create Performance Task grades hardest.
PROCEDURE applyDiscount(price, percent)
{
amount ← price * percent / 100
RETURN (price − amount)
}
Calling it:
sale ← applyDiscount(80, 25)
The arguments (80, 25) are copied into the parameters in order: price = 80, percent = 25. The body computes amount = 20, returns 60. The call expression applyDiscount(80, 25) becomes 60, which is assigned to sale.
Parameter vs. argument (the exam does test the vocabulary): parameters are the names in the definition; arguments are the values in the call. Order is everything — applyDiscount(25, 80) computes a very different discount.
Not every procedure returns a value; some just do things (display output, move a robot):
PROCEDURE greet(name)
{
DISPLAY ("Hello,")
DISPLAY (name)
}
PROCEDURE triple(x)
{
RETURN (x * 3)
}
a ← 4
b ← triple(a + 1)
DISPLAY (b + triple(2))
Trace: a + 1 evaluates first → 5 → becomes x inside triple → returns 15 → b = 15. Then triple(2) → 6. Display 15 + 6 = 21.
Rules that earn points: 1. Arguments are evaluated, then copied. The parameter is a new variable; changing it inside the procedure does not change the caller's variable (Lesson 7's copies-not-links, again). 2. RETURN exits NOW. Code after an executed RETURN is dead. A RETURN inside a loop ends the whole procedure mid-loop — the favorite trick:
PROCEDURE findFirst(list, target)
{
i ← 0
FOR EACH item IN list
{
i ← i + 1
IF (item = target)
{
RETURN (i) ← exits on the FIRST match
}
}
RETURN (-1) ← runs only if the loop finishes with no match
}
This is Lesson 12's first-occurrence search, cleaner: the early RETURN is the guard. findFirst(["a","b","a"], "a") → 1, not 3.
Procedural abstraction = giving a name to a computational process and using the name instead of the steps. The CED's claims:
Exam phrasing to expect: "Which is a benefit of using the procedure?" Correct answers say manage complexity, avoid duplication, single point of change. Wrong answers say runs faster, uses less memory, prevents all errors — procedures do none of that automatically.
Spec: "Write a procedure countAbove(nums, cutoff) returning how many values in nums exceed cutoff."
Recipe: (1) name + parameters from the spec; (2) pick the silhouette (count-matches, Lesson 12); (3) adapt the condition; (4) RETURN the result:
PROCEDURE countAbove(nums, cutoff)
{
count ← 0
FOR EACH n IN nums
{
IF (n > cutoff)
{
count ← count + 1
}
}
RETURN (count)
}
Sequencing ✓ selection ✓ iteration ✓ parameter ✓ return ✓ — this shape is the Create PT procedure requirement satisfied in nine lines.
Problem: What is displayed?
PROCEDURE square(n)
{
RETURN (n * n)
}
DISPLAY (square(3) + square(4))
Solution: square(3) → 9; square(4) → 16; displays 25.
Problem: What is displayed?
PROCEDURE bump(x)
{
x ← x + 10
RETURN (x)
}
n ← 5
result ← bump(n)
DISPLAY (n)
DISPLAY (result)
Solution: bump receives a copy: inside, x becomes 15 and is returned → result = 15. The caller's n was never touched → displays 5, then 15.
Interpretation: "Does the original variable change?" No — arguments are copied into parameters. The distractor (15, 15) bets you think x is n.
Problem: What does check([4, 9, 12, 15]) return?
PROCEDURE check(nums)
{
FOR EACH n IN nums
{
IF (n MOD 2 = 1)
{
RETURN (n)
}
}
RETURN (0)
}
Solution: 4 even → continue. 9 odd → RETURN 9 — procedure over. 12 and 15 never examined. Returns 9.
Interpretation: The trap answer is 15 (the last odd) for students who let the loop "finish." An executed RETURN is a trapdoor, not a bookmark.
Problem: What is displayed?
PROCEDURE f(a)
{
RETURN (a + g(a))
}
PROCEDURE g(b)
{
RETURN (b * 2)
}
DISPLAY (f(3))
Solution: f(3): a = 3 → needs g(3) → b = 3 → returns 6 → f returns 3 + 6 = 9.
Interpretation: Nested calls resolve inside-out, like parentheses. Keep a small call stack on scratch paper: f(3) waiting… g(3) = 6… f = 9. Two levels is as deep as the exam goes — with the trace habit it's mechanical.
bump(n), n is unchanged unless the caller assigns the returned value: n ← bump(n).applyDiscount(25, 80) ≠ applyDiscount(80, 25). Match positions to parameters — the exam plants swapped-order distractors on any two-parameter procedure.PROCEDURE area(w, h) called as area(3, 7), the values 3 and 7 are the:1. (C). Values in the call = arguments; names in the definition (w, h) = parameters. Flashcard it.
What is displayed?
PROCEDURE half(n)
{
RETURN (n / 2)
}
DISPLAY (half(10) + half(6))
2. (A). 5 + 3 = 8.
What is displayed?
PROCEDURE mystery(a, b)
{
IF (a > b)
{
RETURN (a − b)
}
RETURN (b − a)
}
DISPLAY (mystery(4, 9))
3. (B). a = 4, b = 9: 4 > 9 false → skip to second RETURN → 9 − 4 = 5. The procedure computes absolute difference; (A) forgets the ELSE-path flips the subtraction.
What does this display?
PROCEDURE update(val)
{
val ← val * 100
RETURN (val)
}
x ← 7
update(x)
DISPLAY (x)
4. (B). update works on a copy; the returned 700 is discarded (the call isn't assigned to anything). x remains 7. The exam loves the unassigned-return: computing a value ≠ storing it.
5. (A). Capture the returned value back into x. (D) tempts, but a procedure can't assign to the caller's variable — x doesn't exist inside update; that change makes the procedure invalid.
What does locate([7, 2, 7], 7) return?
PROCEDURE locate(list, t)
{
i ← 0
FOR EACH item IN list
{
i ← i + 1
IF (item = t)
{
RETURN (i)
}
}
RETURN (-1)
}
6. (C). Early RETURN fires at the FIRST match: i = 1. (A) is the last-occurrence misread; (D) counts matches instead of locating.
locate([4, 6, 8], 5) return?7. (A). Loop completes with no match → the final RETURN (-1) runs. The sentinel path is real code, not decoration.
8. (A) and (C). Single point of change + readability = procedural abstraction's actual benefits. (B) invents speed; (D) invents safety.
What is displayed?
PROCEDURE outer(n)
{
RETURN (inner(n) + 1)
}
PROCEDURE inner(m)
{
RETURN (m * m)
}
DISPLAY (outer(5))
9. (C). inner(5) = 25, outer returns 25 + 1 = 26. (A) stops one level early; (D) adds instead of squaring.
10. (B). Interchangeable internals — the abstraction contract. Callers see name/parameters/results only; same interface, same behavior, zero caller changes.
What does tally([3, 8, 3, 3], 3) return?
PROCEDURE tally(nums, target)
{
c ← 0
FOR EACH n IN nums
{
IF (n = target)
{
c ← c + 1
}
}
RETURN (c)
}
11. (D). Count the 3s: positions 1, 3, 4 → 3. No early exit here — this one counts every match (contrast problem 6; the presence or absence of RETURN inside the IF is the entire difference between find and count).
12. (Model answer.)
PROCEDURE bestScore(scores)
{
best ← scores[1]
FOR EACH s IN scores
{
IF (s > best)
{
best ← s
}
}
RETURN (best)
}
bestScore([71, 94, 82]) returns 94. Full credit needs: parameter used (scores), selection (IF), iteration (FOR EACH), honest initialization (scores[1], not 0 — Lesson 12!), and a RETURN outside the loop.
Answer letter distribution check: C, A, B, B, A, C, A, A+C, C, B, D — singles: A×3, B×3, C×3, D×1 + multi (A,C). Balanced. Cumulative through L14 ≈ A 24%, B 30%, C 26%, D 20%.
12 (short response, PT-style). Write a procedure bestScore(scores) that returns the highest value in the non-empty list scores. Your procedure must use a parameter, selection, and iteration. State what bestScore([71, 94, 82]) returns.
This lesson is the Create PT. The rubric requires a student-developed procedure that:
The countAbove / tally / bestScore shapes in this lesson satisfy every requirement. Three PT-saving specifics:
Written Response 2(c) rehearsal: "My procedure tally(nums, target) implements procedural abstraction: the main program calls it by name to count matches without containing the counting logic itself. Because the logic lives in one procedure, I fixed a comparison bug in one place and every feature using the count was corrected simultaneously." — Note it hits name, abstraction claim, and single-point-of-change. Build your own version of this paragraph the day your procedure works.
1. (C). Values in the call = arguments; names in the definition (w, h) = parameters. Flashcard it.
2. (A). 5 + 3 = 8.
3. (B). a = 4, b = 9: 4 > 9 false → skip to second RETURN → 9 − 4 = 5. The procedure computes absolute difference; (A) forgets the ELSE-path flips the subtraction.
4. (B). update works on a copy; the returned 700 is discarded (the call isn't assigned to anything). x remains 7. The exam loves the unassigned-return: computing a value ≠ storing it.
5. (A). Capture the returned value back into x. (D) tempts, but a procedure can't assign to the caller's variable — x doesn't exist inside update; that change makes the procedure invalid.
6. (C). Early RETURN fires at the FIRST match: i = 1. (A) is the last-occurrence misread; (D) counts matches instead of locating.
7. (A). Loop completes with no match → the final RETURN (-1) runs. The sentinel path is real code, not decoration.
8. (A) and (C). Single point of change + readability = procedural abstraction's actual benefits. (B) invents speed; (D) invents safety.
9. (C). inner(5) = 25, outer returns 25 + 1 = 26. (A) stops one level early; (D) adds instead of squaring.
10. (B). Interchangeable internals — the abstraction contract. Callers see name/parameters/results only; same interface, same behavior, zero caller changes.
11. (D). Count the 3s: positions 1, 3, 4 → 3. No early exit here — this one counts every match (contrast problem 6; the presence or absence of RETURN inside the IF is the entire difference between find and count).
12. (Model answer.)
PROCEDURE bestScore(scores)
{
best ← scores[1]
FOR EACH s IN scores
{
IF (s > best)
{
best ← s
}
}
RETURN (best)
}
bestScore([71, 94, 82]) returns 94. Full credit needs: parameter used (scores), selection (IF), iteration (FOR EACH), honest initialization (scores[1], not 0 — Lesson 12!), and a RETURN outside the loop.
Answer letter distribution check: C, A, B, B, A, C, A, A+C, C, B, D — singles: A×3, B×3, C×3, D×1 + multi (A,C). Balanced. Cumulative through L14 ≈ A 24%, B 30%, C 26%, D 20%.
Exam tip: On any procedure trace, write the call's argument values above the parameter names before reading the body — x=5 in the margin — and the moment you hit RETURN, draw a line: nothing below it executes. Those two pencil habits (bind, then trapdoor) cover every procedure distractor the exam owns.