Over the past decade, I have been thinking about how programming languages evolve and what survives the churn. With the recent rise of AI coding assistants, developers are increasingly exposed to a variety of programming languages in a single workday. An LLM will happily generate Python, Rust, Go, or CUDA for you. It does not care about your language allegiance. This polyglot reality raises a question: what are the essential programming constructs every developer should internalize, independent of any particular language?
There is no better place to start than Niklaus Wirth's Algorithms + Data Structures = Programs, first published in 1976. The title itself is a thesis statement. A program is not a sequence of clever tricks. It is the composition of well-chosen data representations with algorithms that operate on them. Wirth's argument is that the two are inseparable and must be designed together.
The book
Wirth structures the book around a progression from simple to complex, in both data and control:
- Fundamental data structures. Arrays, records, sets, and sequences. Wirth introduces these not as language features but as concepts with concrete machine representations.
- Sorting. Straight insertion, selection, exchange, then Shell sort, heapsort, and quicksort. Wirth analyzes them, counting comparisons and moves.
- Recursive algorithms. Recursion as a first-class algorithmic technique, connected to the call stack.
- Dynamic data structures. Linked lists, trees, AVL trees, B-trees. The B-tree chapter is one of the clearest treatments of the topic from that era.
- Key transformations. Hash tables, collision resolution, chaining vs open addressing.
- Language structures and compilers. The final chapter is a surprise for a data structures textbook: BNF grammars, recursive descent parsing, and code generation.
What holds up
- The inseparability of data and algorithms. Choose the data representation first, and the algorithm often follows naturally. A discipline modern "move fast" culture tends to skip.
- Explicit cost models. Wirth counts comparisons and memory accesses. In an era where developers invoke library functions without understanding their complexity, this is valuable.
- The compiler chapter. Having a mental model of how languages are parsed, type-checked, and compiled gives you a significant edge in debugging AI-generated code that looks correct but is subtly wrong.
- Representation matters. The same abstract data type can have wildly different performance depending on its physical representation: AoS vs SoA, linked list vs contiguous buffer, chaining vs open addressing. These choices show up in cache miss rates and memory allocation patterns.
What shows its age
- Concurrency is absent. No locks, atomics, message passing, or parallel algorithms.
- No discussion of memory hierarchy. Wirth's cost model counts comparisons, not cache lines. On modern hardware, a linked list traversal and an array scan of the same logical data can differ by an order of magnitude purely due to memory access patterns.
- The language choice. Pascal, Modula-2, and Oberon are not what anyone ships production code in today.
- The scope is narrow. No graphs beyond trees, no probabilistic data structures, no persistent structures.
- No treatment of testing or correctness. Wirth asserts correctness through careful construction.
Why it matters now
The paradox of AI-assisted programming is that it simultaneously lowers the barrier to writing code and raises the bar for understanding it. When an LLM generates a red-black tree or a merge sort in a language you have never used, you need a mental framework to evaluate whether it is correct, efficient, and appropriate. You need to know what questions to ask: Is this O(n log n) or O(n^2)? Does it allocate on the heap or the stack? What happens under contention?
Wirth's book provides that framework. Not because it covers every modern topic but because it teaches a way of thinking. Data and algorithms are not separate concerns. Representation determines performance as well as developer experience. Abstraction has a cost. The machine is not infinitely fast, memory is not infinitely cheap, and developer attention span continues to decline.
Wirth's title is the thesis: programs are data structures plus algorithms. In the AI era, the LLM writes the code and you provide the judgment. That judgment is exactly what Wirth's book trains: representation choice, cost models, and the discipline of designing data and algorithms together.
The paradox of AI-assisted programming is that it lowers the barrier to writing code and raises the bar for understanding it.