First-class and higher-order functions: treating behavior as data
JavaScript's own array-methods lesson used .map(), .filter(), and .reduce() without naming the underlying idea that makes all three possible. That idea — a function is a value, exactly like a number or a string — is the single feature functional programming is most directly named after.
Beginner
2 min read
"First-class" means a function can go anywhere a value can go
def double(x): return x * 2my_function = double # assigned to a variable, like any other valuefunctions = [double, abs] # stored in a list, like any other valuedef apply(f, x): # passed AS AN ARGUMENT, like any other value return f(x)apply(double, 5) # 10
A language has first-class functions when a function can be assigned to a variable, stored in a data structure, passed as an argument, and returned from another function — treated exactly like any other value (a number, a string, a list) rather than existing only as something you call, never hold. Python, JavaScript, and Go (this curriculum's own previous domains) all support this; it's a foundational enough feature that most modern languages have it, even ones that aren't otherwise "functional" by design.
Higher-order functions: functions that take or return other functions
A higher-order function either accepts a function as an argument, returns a function, or both — apply_twice takes f as a parameter and calls it. .map(), .filter(), and .reduce() (this curriculum's own JavaScript array-methods lesson) are all higher-order functions: each takes a function describing what to do to each element and handles the actual iteration internally, so the caller never writes the loop itself.
Why this is more than just a syntax convenience
Passing behavior as a value means a higher-order function like .filter() can be written once, correctly, and reused for every possible filtering condition a caller might need — the loop itself (a genuinely easy place to introduce an off-by-one error, or forget an edge case) is written and tested exactly once, inside .filter()'s own implementation, rather than being rewritten slightly differently every time a new piece of code needs to filter something. This is the same "paved road" principle Application Security's own lesson named for security-relevant code, applied here to correctness in general: a well-tested, reusable higher-order function removes an entire class of repeated, error-prone code from every call site that uses it.
make_multiplier returns a new function each time it's called, and that returned function "remembers" the specific factor it was created with — this is a closure (JavaScript's own scope-and-closures lesson covered the mechanism directly), and it's the foundation the next lesson's partial application and currying build on: a function that returns a specialized version of itself, configured with some arguments already fixed.