4 ms·
Sorry in advance for this; I think I put my pedant pants on this morning by mistake. I agree that complexity doesn't scale linearly. That's a very insightful t
by benjamincburns 13y ago
Sorry in advance for this; I think I put my pedant pants on this morning by mistake.
I agree that complexity doesn't scale linearly. That's a very insightful thing to note. However, the fact that LOC correlates with "probability of a change causing unintended consequences" in many codebases is coincidental rather than causal. The underlying cause of the unintended consequences is almost always poor structure and/or poor planning.
Two words: cohesion and coupling.
Highly cohesive systems which are loosely coupled are far easier to extend and modify without fear of weird and unintended "spooky action at a distance" interactions.
- Aylw 13y agoWhile this is true, keeping a large project from getting ... err, decohesed and coupled, takes a lot of time as well. You will have less lines of code, but you'll definitely spend a lot more time than that first 1000 lines on a large project.
- zeteo 13y agoBeyond Aylw's very good point that loose coupling demands its own share of effort, I'd also like to add that it only delays the inevitable. Even if you manage to organize your modules in a perfect, non-leaking tree and to only reference bug-free, well-documented external libraries, you still have two fundamental problems: 1. Each module necessarily has access to functionality provided by all its "ancestors". In the best case, this number still grows logarithmically with project size, and accordingly the difficulty of adding or modifying code in a "leaf" module. 2. New libraries and language features are generally seen as a neverending bonanza. But before you can effectively modify a module you need to understand how it currently works, which necessarily involves understanding the external tools used in it (quirks and all). As the variety of these external tools increases with code size (at quite possibly a super-linear rate), the complexity of working with any given module deepens accordingly. The Holy Grail of software development would of course be perfect layering: each layer completely masks its predecessor, and is no more complex. Someone who achieved it could indefinitely roll off as much useful code on day 500+ as they did on day 1. But I'm not aware of any practice or methodology that dares to even remotely promise such utopian benefits.
- benjamincburns 13y agoAgain, I was being pedantic. I should really work on that. I didn't explain clearly enough that I agree with your assessment that as a codebase grows the effort involved in maintaining/adding to/modifying it grows as well. However I disagreed with what you said was the main reason for this. I think that your "main reason" is definitely a contributing factor, but it's too complex to be boiled down like that. I also agree that maintaining a properly structured project definitely takes considerable effort. Further I'd argue that when this is done well the effort is largely front-loaded. This means that as the program matures, the effort required to implement new features of a given complexity will largely taper off. I believe this is the best-case logarithmic growth you're talking about. Obviously worse cases would be linear, quadratic, and so-on. I view the differences between these curves as essentially the amortized value gained by doing this kind of front-loaded architectural work. If you get it perfect, you gain the difference between log(n) and perhaps some kⁿ, depending on project size/scope. Speaking of scope, this ideal is only achievable where project scope is relatively well defined and relatively static throughout the life of the project. Sure, you can make a spam filter play chess, but, well, you get the idea... And yes, leaky abstractions, complicated tools, all of that definitely contributes in horribly awful, ugly, hard-to-predict ways. If you care to read my thoughts on this topic in particular, I think I summed them up nicely in my reply to this comment [1] on the short-lived topic "Why I hate Frameworks." Boiling all of this down, I think all I'm really getting at is that complexity drives effort, but there are ways of minimizing the complexity of large codebases. Sure external forces often make this minimization effort obnoxiously difficult, but it's still possible. While we might disagree on what "often" really means in the prior sentence, I think otherwise we're wholly on the same page. Anyway, I'll try to go change my pants... 1: https://news.ycombinator.com/item?id=6284038 https://news.ycombinator.com/item?id=6284038