Skip to content

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

📝 Notes

  • Functions can return multiple values — the foundation of the (result, error) idiom.
  • Named returns pre-declare result vars; a bare return returns them. Useful with defer to set err on recovery, but don't overuse — they can hurt readability.
  • defer schedules 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 with sum(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 the defer line. 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

  1. Q: In what order do deferred calls run, and when are their arguments evaluated?
    ALIFO (reverse of declaration); arguments are evaluated immediately at the defer statement.
  2. Q: What's the idiomatic signature for a function that can fail?
    AReturn the result(s) plus a trailing error: 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

  • recover semantics — 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 mathutil package.

Time spent Difficulty Confidence
100 min 🟦🟦⬜⬜⬜ 🟦🟦🟦⬜⬜

Suggested commit: feat(examples): functions, multiple returns, defer; calculator (day 005)