# Trade-offs and Performance Pitfalls — Functional Programming Concepts

Source: https://www.geekswithgeeks.com/en/functional-programming/pr-tradeoffs

> Where FP style costs more than it gives.

## Know the costs

Common pitfalls in JavaScript-style FP: **long chains** of `map`/`filter` allocate an intermediate array per step (usually fine; matters in hot paths over large data); **spreading inside reduce** copies the accumulator every iteration, turning linear work quadratic; **deep copying** whole state trees instead of path copying; **recursion** on unbounded input without tail-call optimisation; **memoisation** that leaks memory or keys on object identity. Readability costs matter too: heavy point-free code, unfamiliar abstractions (monad transformers, custom operators) and mismatched team conventions slow reviews. Measure with a profiler before optimising, and choose the style that your team can read.

## Quadratic reduce and a linear fix

Both are pure from the caller's point of view.

```typescript
type Item = { id: string; value: number };

// Quadratic: copies the growing object on every step
const indexSlow = (items: Item[]) =>
  items.reduce<Record<string, Item>>((acc, it) => ({ ...acc, [it.id]: it }), {});

// Linear: local mutation of a fresh object that never escapes half-built
function indexFast(items: Item[]): Record<string, Item> {
  const acc: Record<string, Item> = {};
  for (const it of items) acc[it.id] = it;
  return acc;
}

// Or use a built-in that does the same
const indexBuiltIn = (items: Item[]) =>
  Object.fromEntries(items.map(it => [it.id, it] as const));
```

## Local mutation is fine

A function that mutates only objects it created itself, and returns them without exposing intermediate states, is still pure from the outside. Purity is about observable behaviour.

**Quiz:** Why can `reduce` with object spread on every step be slow?

- [ ] Spread syntax runs network requests
- [ ] reduce is not optimised by engines
- [x] It copies the whole accumulator each iteration, making the work quadratic
- [ ] Objects cannot be returned from reduce

*Answer:* It copies the whole accumulator each iteration, making the work quadratic. Copying grows with the accumulator size.
