Conceptly
← All Concepts
🎯

First-Class Function

FunctionsFunctions treated as values

First-class functions mean a language treats functions as values. A function can be assigned to a variable, passed as an argument, returned from another function, or stored in an array or object β€” the same way any other value can.

β–ΆArchitecture Diagram

πŸ”— Relationship

Dashed line animations indicate the flow direction of data or requests

Why do you need it?

When a language forces you to name every piece of behavior upfront and call it only by name, you end up writing repetitive logic that differs in just one small step. The structure of an algorithm has to be copied each time you want to vary a single part of it. If functions could be passed around like data, you could write the shared structure once and supply only the part that changes. Without first-class functions, that kind of abstraction is either impossible or requires awkward workarounds.

Why did this approach emerge?

Early mainstream languages treated functions as special constructs that lived outside the normal value system. You could not put a function in a variable or hand it to another function directly. Lisp and later functional languages demonstrated that treating functions as ordinary values made code significantly more composable. As programming evolved toward handling more complex behavior β€” event systems, asynchronous operations, pipelines β€” the need to pass and store behavior became unavoidable. Languages that adopted first-class functions gained expressive power that was difficult to replicate otherwise.

How does it work inside?

In a language with first-class functions, a function definition produces a value β€” just like a numeric literal or a string produces a value. That value can be bound to a name with an assignment, passed into another function through a parameter, returned from a function as its output, or placed inside a data structure like an array or an object. The four capabilities β€” assign, pass, return, store β€” follow from the single rule that functions are values. Nothing special needs to happen for any of them; they work the same way all other values work.

In Code

Assigning a function to a variable

const greet = (name: string) => `Hello, ${name}`;

const sayHello = greet; // functions are values
console.log(sayHello('Alice')); // 'Hello, Alice'

A function assigned to a variable is still just a value. You can copy it to another variable and call it from there β€” the behavior travels with the reference.

Passing a function as an argument

function applyTwice(fn: (x: number) => number, value: number) {
  return fn(fn(value));
}

const double = (x: number) => x * 2;
console.log(applyTwice(double, 3)); // 12

The shared logic β€” apply something twice β€” is written once. The specific behavior is supplied at the call site. This is only possible because functions are values.

Boundaries & Distinctions

First-class functions and higher-order functions are closely related but describe different things. First-class function is a property of the language: it means functions can be used anywhere a value can. Higher-order function is a property of a specific function: it means that function accepts another function as input or returns one as output. You need first-class functions before higher-order functions are possible, but having first-class functions does not automatically mean every function is higher-order.

When should you use it?

First-class functions show up wherever a system needs to store, route, or inject behavior instead of only data. Event systems keep handlers in registries, sorting APIs accept different comparison functions, and servers often map URLs or message types to handler functions in a dispatch table. UI code does the same thing with render props, builder callbacks, and other places where part of the rendering behavior is passed in from the outside. In all of those cases the architectural move is the same: behavior can travel through variables, collections, and APIs as a value, which is exactly what first-class functions make possible.

Event handlingStrategy patternDeferred executionConfiguration