Comment by sayrer
10 years ago
"The classic solution to every combinatorial explosion is modularity: separation of concerns."
What is the basis for this comment? It sounds reasonable, but how would one test it?
10 years ago
"The classic solution to every combinatorial explosion is modularity: separation of concerns."
What is the basis for this comment? It sounds reasonable, but how would one test it?
I've been having a long-running private discussion with the author about this. My anti-modularity stance: http://akkartik.name/post/modularity. However this is a sane use of modularity. My point is mostly that just adding more module boundaries without thought isn't always a net win. So I guess I'd change the statement you quoted to "the right separation of concerns." And the right separation takes trial and error to discover.
Well, of course, your separation of concerns is only as useful as the boundary is well thought.
Modularity is not a magic wand (Brooks' "silver bullets" aren't an strong enough concept for what you are debunking) that makes all the problems of software developing go away.
Not sure if you found me super insightful :) or yawn obvious, but I was responding to the quote that modularity is the solution to complexity. We're surrounded by software that made that mistake and ended up adding complexity instead of reducing it.
1 reply →
Complexity grows (a lot) faster than the number of parts. A module with n parts can have O(n^2) pairwise interactions, so the potential for bugs (and debugging costs) grows faster than code size.
Many features of high level languages are attempts to add modularity and thus break the complexity up into manageable pieces. Functions, classes with "private" features, UNIX-style[1] tools, and other types of modular programming are ways to separate local complexity from the global environment.
A complex module with many internal parts adds a lot of complexity to a program, but by restricting the interfaced we greatly reduce how much complexity is exposed to the parent environment. A simple interface with only a few parts can hide many more parts that would have otherwise been potential interactions with the global environment (bug/attack surface).
Even better, well defined interfaces allow the separate modules to be implemented and debugged separately. Which would you rather debug? One 1000-line program or 10 separate 100-line programs? While they are the same amount of code, smaller programs are much easier to understand[2].
[1] http://www.catb.org/esr/writings/taoup/html/ch01s06.html#id2...
[2] http://www.catb.org/esr/writings/taoup/html/ch01s06.html#id2...
TL;DR - "KISS: Keep It Simple, Stupid!"
IE, You want the complexity of extra code to be additive, not multiplicative.
I don't actually have a cite for you, although it comes up in information theory. For example, guessing a password one letter at a time is (dramatically) easier than guessing the whole thing at once. I'd be curious to know what the term for it is.
Edit: "factoring" is one word for it.
I'd call it independence.
Divide and conquer?
Steve McConnell's Code Complete and John Holland's work on technological evolution suggest themselves. Modularity tends to contain complexity generally.