Overview
5 min read
Functions are the workhorse of any program, and you already write them every day in TypeScript and JavaScript. This section maps each piece you know — declarations, parameters, return values, arrow functions, higher-order functions, function pointers, and recursion — onto its idiomatic Rust counterpart. The syntax is close enough to feel familiar, but a few deeper ideas (typed signatures as hard contracts, the expression-oriented body, the Fn/FnMut/FnOnce closure traits, and the absence of default/rest parameters and guaranteed tail-call optimization) reshape how you read and write Rust code.
What’s in This Section
Section titled “What’s in This Section”- Basic Functions and Signatures -
fndefinitions, typed parameters, return types, statements vs expressions - Function Parameters - no default or rest parameters; idiomatic alternatives (
Option<T>, slices, structs, traits) - Return Values - return types, tail expressions, the unit type
(), early return, returning tuples - Arrow Functions vs Closures -
|args|syntax,Fn/FnMut/FnOnce, capture by reference vsmove - Higher-Order Functions -
map/filter/reduceequivalents, taking and returning closures - Function Pointers - the
fntype, passing named functions, function items vs closures - Recursion - recursive functions, stack depth, iterative alternatives, recursive enums with
Box
What You’ll Learn
Section titled “What You’ll Learn”By the end of this section, you will be able to:
- Write Rust functions with
fn,snake_casenames, mandatory typed parameters, and a-> Typereturn arrow - Use the tail expression (last line, no semicolon) as the return value, and reserve
returnfor early exits - Reproduce default, optional, and rest parameters with
Option<T>, slices&[T],Defaultstructs, and the builder pattern - Return multiple values as a tuple (or a named struct) instead of mutating out-parameters
- Translate arrow functions into Rust closures and understand capture by
&,&mut, andmove - Distinguish the three closure traits —
Fn,FnMut,FnOnce— and accept the weakest one that works - Take closures as parameters (
impl Fn) and return them (impl FnorBox<dyn Fn>) - Pass named functions and constructors as function pointers (
fn(T) -> R) - Write recursion safely, knowing Rust has no guaranteed tail-call optimization, and reach for iteration or
Boxwhen appropriate
Topics
Section titled “Topics”| # | Topic | What it covers |
|---|---|---|
| 1 | Basic Functions and Signatures | fn definitions, typed parameters, the -> return type, statements vs expressions; vs TS declarations |
| 2 | Function Parameters | No default/rest params; Option<T>, slices &[T], Default structs, builders, “overloading” via traits |
| 3 | Return Values | Return types, implicit tail-expression return, the unit type (), early return, returning tuples |
| 4 | Arrow Functions vs Closures | (args) => becomes |args|; Fn/FnMut/FnOnce; capture by reference vs move; the move keyword |
| 5 | Higher-Order Functions | map/filter/reduce (lazy iterators); taking impl Fn and returning impl Fn / Box<dyn Fn> |
| 6 | Function Pointers | The fn type, passing named functions, function items vs fn pointers vs closures |
| 7 | Recursion | Recursive functions, no guaranteed TCO, stack depth, iterative alternatives, recursive enums with Box |
Learning Objectives
Section titled “Learning Objectives”After completing this section, a TypeScript/JavaScript developer should be able to:
- Read any Rust function signature and explain its parameters and return type as a compiler-enforced contract.
- Explain why a stray semicolon changes a function’s return value to
(), and fix the resultingmismatched typeserror. - Choose the right idiom for “flexible” arguments:
Option<T>, a slice, aDefaultstruct, a builder, or a trait bound. - Write closures with inferred types, decide when
moveis required, and pick the correctFn/FnMut/FnOncebound. - Build lazy iterator pipelines (
iter().filter().map().collect()) as the replacement for eagerArray.prototypechains. - Decide between a
fnpointer and a genericimpl Fnbound for a callback parameter. - Recognize when recursion is safe (shallow, recursive data) versus when iteration is the safer Rust default.
Prerequisites
Section titled “Prerequisites”This section assumes you have completed:
- Section 02: Basics — variables and mutability (
let mutis essential forFnMut), the basic types you will pass as parameters, and especially the statement-vs-expression distinction that underpins tail-expression returns.
If the expression-oriented model (let x = { ...; a + b };) feels unfamiliar, re-read the Basics section before starting here.
Note: Several topics in this section preview concepts covered fully later: ownership and
move(Section 05),Option/Resultand the?operator (Section 08), generics and traits (Section 09), andBox/Rcfor recursive types (Section 10). You do not need those sections first — the links are there for when you want to go deeper.
Estimated Time
Section titled “Estimated Time”- Reading: 3-4 hours
- Hands-on Practice & Exercises: 3-4 hours
- Total: 6-8 hours
A reasonable order is the list order above: basics → parameters → return values → closures → higher-order → function pointers → recursion. Closures (topic 4) are the conceptual heart of the section, so do not skip them.