Functional programming treats functions as first-class values: they can be assigned to variables, passed as arguments, returned from other functions, and stored in data structures. A function that takes one or more functions as arguments, or that returns a function as its result, is called a higher-order function. The familiar array methods \( \text{map} \), \( \text{filter} \), and \( \text{reduce} \) are all higher-order functions, and they form the backbone of functional data processing. Closures and lexical scoping are intimately connected with this style: a closure is a function that captures and remembers variables from its enclosing lexical scope, even after that scope has finished executing, and lexical scoping means a variable's scope is determined by its position in the source code rather than by the runtime call stack.
Currying and partial application are two related techniques for working with multi-argument functions. Currying transforms a function of \( n \) arguments into a sequence of \( n \) single-argument functions, so that \( \text{add}(a, b) \) becomes \( a \mapsto b \mapsto a + b \); in Haskell every function is automatically curried. Partial application, by contrast, fixes some arguments of a function to produce a new function with fewer parameters, and it can fix multiple arguments at once. Currying enables partial application, but the two are distinct: currying is a structural transformation of a function's shape, while partial application is about pre-filling specific values.
Closely related are function composition, which combines functions so the output of one becomes the input of the next, and piping, which provides a more readable left-to-right data flow. Elixir and F# use the pipe operator \( \rvert \), while Haskell composes functions right-to-left with the dot operator. Together with point-free style — defining functions without explicitly naming their arguments, so that \( s \mapsto s.\text{toUpperCase}() \) becomes \( \text{map}(\text{prop}('\text{name}')) \) — these techniques let programmers build expressive transformation pipelines out of small, reusable pieces. Eta reduction is the corresponding simplification that removes redundant parameter passing when a function merely forwards its argument to another function, while eta expansion is its inverse, wrapping a function to make its type explicit.