Lesson 1 / 25

What Functional Programming Is

Describe what to compute, not every step of how.

Declarative versus imperative

Functional programming (FP) treats computation as the evaluation of functions: values flow into functions and new values flow out. Imperative code describes how to reach a result step by step, mutating variables along the way. Declarative code describes what the result is, for example "the names of active users", and leaves the looping to library functions. FP is a style more than a language feature: Haskell enforces it, while JavaScript, TypeScript, Python, Kotlin and many others let you use it as much as you like. Its core ideas are pure functions, immutable data, functions as values and composition.

Computation as evaluating functions

Functional programming builds programs from functions that map inputs to outputs, keeping side effects few and visible.

Three ideas: what FP is, pure functions, and side effects.
Figure 1.1 — From declarative style to pure functions to isolated effects.

The same task in two styles

Collecting the names of active users.

type User = { name: string; active: boolean };

// Imperative: how, with a mutable accumulator
function activeNamesImperative(users: User[]): string[] {
  const result: string[] = [];
  for (let i = 0; i < users.length; i++) {
    if (users[i].active) {
      result.push(users[i].name);
    }
  }
  return result;
}

// Declarative / functional: what, as a pipeline of transformations
const activeNames = (users: User[]): string[] =>
  users.filter(u => u.active).map(u => u.name);

A recipe versus an order

Imperative code is a recipe telling the cook every step; declarative code is ordering "a vegetarian pizza" and trusting the kitchen to know the steps.

Quick check: Which statement best describes declarative code?

  • It cannot be written in JavaScript
  • It always runs faster than imperative code
  • It states what result is wanted and delegates the step-by-step control flow
  • It avoids using functions
Answer

It states what result is wanted and delegates the step-by-step control flow — Declarative code focuses on the result; performance depends on the implementation.