Day 005 — Functions, Multiple Returns & defer¶
Month 1 · Week 1 · ⬅ Day 004 · Day 006 ➡ · Journal index
🎯 Learning Objective¶
Write functions with multiple/named returns, use defer, variadics, and closures.
📚 Topics¶
- Multiple & named returns ·
defer(LIFO) · variadic params · closures · first-class functions
📖 Reading / Sources¶
- Learning Go ch.5
- Effective Go — Functions, defer
📝 Notes¶
- Functions can return multiple values — the foundation of the
(result, error)idiom. - Named returns pre-declare result vars; a bare
returnreturns them. Useful withdeferto seterron recovery, but don't overuse — they can hurt readability. deferschedules a call to run when the surrounding function returns, in LIFO order. Arguments are evaluated at defer time, not at run time. Idiomatic for cleanup:defer f.Close().- Variadic
func sum(n ...int)collects args into a slice; call withsum(s...)to spread. - Closures capture variables by reference — a function returned from another can keep mutating captured state (e.g. a counter).
- Functions are first-class values: assign them, pass them, return them.
💻 Code Examples¶
func divmod(a, b int) (int, int, error) {
if b == 0 { return 0, 0, errors.New("division by zero") }
return a / b, a % b, nil
}
defer fmt.Println("runs last") // LIFO: deferred calls unwind in reverse
Full code:
examples/functions/main.go· Calculator:exercises/.../calculator
🏋️ Exercises / Practice¶
| Exercise | Status | Link |
|---|---|---|
divmod returning (q, r, err) |
✅ | examples/functions |
Calculator Apply(op,a,b) + ErrDivByZero |
✅ | calculator |
| Closure counter | ✅ | examples/functions |
🐛 Mistakes Made¶
- Assumed
defer'd args evaluate when the deferred call runs — they actually evaluate immediately at thedeferline. Verified with a small experiment. - Forgot a closure shares the captured variable; two closures over the same var saw each other's changes.
❓ Open Questions¶
- Pre-Go 1.22 loop-variable capture bug — does it still bite? (Go 1.22+ gives each iteration its own variable; older code can leak.) Note for concurrency month.
🧠 Active Recall¶
- Q: In what order do deferred calls run, and when are their arguments evaluated?
A
LIFO (reverse of declaration); arguments are evaluated immediately at thedeferstatement. - Q: What's the idiomatic signature for a function that can fail?
A
Return the result(s) plus a trailingerror:func() (T, error).
🪶 Feynman Reflection¶
A Go function can hand back several things at once, which is why "return the value and an error" is everywhere. defer is a "do this on the way out" note that stacks up and runs in reverse — perfect for closing things you opened.
🕳️ Knowledge Gaps¶
recoversemantics — only previewed; full treatment in Week 3 (panic/recover).
✅ Summary¶
I can structure functions idiomatically, clean up with defer, and use closures.
⏭️ Next Steps / Prep for Tomorrow¶
- Day 006: packages & modules — extract a reusable
mathutilpackage.
| Time spent | Difficulty | Confidence |
|---|---|---|
| 100 min | 🟦🟦⬜⬜⬜ | 🟦🟦🟦⬜⬜ |
Suggested commit: feat(examples): functions, multiple returns, defer; calculator (day 005)