~ / track D / fp foundations

Imperative vs declarative

Basic

In the imperative style you describe how to reach the result: step by step, mutating state. In the declarative style you describe what you want, and the runtime takes care of the how. The same result, but written closer to your intent.

Minimal example

Imperative (pseudocode, with mutation) — every detail of the loop is spelled out:

let total = 0;
for (let i = 0; i < xs.length; i++) {
  if (xs[i] % 2 === 0) total += xs[i] * xs[i];
}

Declarative in Clojure — filter, square, sum. No indices, no mutation:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

Step through the pipeline

Use the controls to apply one stage at a time. The declarative pipeline above is the static description of exactly this animation:

map / filter / reduce

input
123456

Practical example

The same shape works on richer data. Compute the total spent by customers from "BR" without a single for loop or temporary variable:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

The pipeline reads top-to-bottom like a sentence: "from orders, keep the BR ones, take their amounts, sum them." The transformation order is the reading order.

Check yourself

? quiz

Which property best characterizes the declarative version above?

Exercise

Rewrite the imperative description below as a declarative Clojure pipeline:

"From the orders above, keep only those with amount greater than 100, take the customer names, and return them as a sorted vector."

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate
 status: new