Functions
return is only an early exit
Since a block already hands back its last expression, you mostly won’t write return at all. It’s here for exactly one job: leaving a function early, before that last line.
The two returns are guard clauses; fall past both and the final 0 is the normal result.
Recursion just works, too — a fix name is in scope inside its own definition, so a function can call itself:
factorial refers to factorial while it’s still being defined, and since the body only runs when it’s called, the name is ready by then. (Two functions that call each other — mutual recursion — is the one case this doesn’t cover yet.)