TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Redundancy vs. dependencies: which is worse? (2008)

130 pointsby ripitrustalmost 10 years ago

8 comments

d--balmost 10 years ago
This article is very important. I encourage everyone to read it, as it raises a lot of good points.<p>In my opinion, the problem it describes come from the vagueness of the concept of elegance, and how counterintuitive it is. It doesn&#x27;t even have to imply modules or anything like that. In the simplest form it boils down to:<p>Would you rather write:<p><pre><code> if (a) { doSomething(); if (b) { doSomethingElse(); } } </code></pre> or<p><pre><code> if (a &amp;&amp; b) { doSomething(); doSomethingElse(); } else if (a &amp;&amp; !b) { doSomething(); } </code></pre> Of course, there is no true answer to that question, and it always depends on the context. But many programmers will never ever consider option 2. And that is for two good reasons: 1, you make one more test, and 2 you duplicate the function call do doSomething(), so your program is larger. So mathematically speaking option 1 is more elegant, it&#x27;s shorter, it&#x27;s faster, it&#x27;s lighter, what&#x27;s not to like?<p>Well, multiply the ifs and the elses, and you will soon find out that option 2 is much more readable and changeable, which is the more elegant solution to anyone who&#x27;s an engineer rather than a mathematician.<p>The tension it describes is that in every programmer is a mathematician and an engineer endlessly conflicting. This should be a good guidance for which style to use. Is this code a math code, or is it engineer&#x27;s code. When you can answer that question, you can decide which style to write your code in.
评论 #9731117 未加载
评论 #9731504 未加载
评论 #9731180 未加载
评论 #9731762 未加载
评论 #9731227 未加载
评论 #9731003 未加载
评论 #9731259 未加载
评论 #9731014 未加载
评论 #9732035 未加载
评论 #9731271 未加载
rsp1984almost 10 years ago
The article makes some very important points and it&#x27;s certainly worth a read for every programmer.<p>What the article misses to address explicitly however is that the whole redundancy vs. dependency conflict is caused by modularization. Without modules there would be no conflict.<p>So the real questions to answer here are: When do you need modules or do you need them at all? What should be modularized? And, most importantly, how to choose smart boundaries? Good answers to these questions will save a project from a world of pain down the road.<p>The classic OOP &#x2F; software engineering education these days lacks critical debate about software modularization. Modularization is almost always presented as a good thing. What nobody tells you however is that in real world engineering, on real world teams, modularization can cause <i>a lot</i> of trouble if not done the right way.
评论 #9731990 未加载
评论 #9731071 未加载
评论 #9731044 未加载
telalmost 10 years ago
It&#x27;s kind of funny how, rightfully, the author paints a picture where the &quot;horrible, enlightened external dependency&quot; itself is antimodular to the T. Given that all modules supposedly have stable interfaces, documentation, tests, reasonable size, yada yada then one might expect that each of their dependencies takes advantage of these properties to maintain light and wonderful themselves.<p>Of course, this is a situation that&#x27;s highly incompatible with C. Let&#x27;s ditch that.<p>In ML modules are king. You probably make hundreds in any non-trivial program and the compiler will beat your ass if you muck up their interfaces. Anywhere. Packages are just sets of 3 public modules wrapped up in twine and a README file (coincidentally this is where &quot;ownership and lifecycle&quot; are managed, but, sorry, I&#x27;m going to ignore those for a moment).<p>This could be every bit as bad as I described before, but ML also realized that modules which just form a big dependency tree are actually quite annoying. The whole reason we define public APIs is so that there can be multiple satisficing inplementors, but this cannot be in 99% of module technologies today.<p>So ML has functors (not Haskell functors, certainly certainly certainly not C++ functors) which are &quot;parameterized modules that actually work&quot;. One could distribute their command line parsing module with a pluggable serialization and a pluggable help display. See MirageOS for a giant example of this kind of system working out.<p>Does it really work?<p>Probably not. It&#x27;s not in most maintainers DNA to functor-ize everything. It&#x27;s even a significant challenge to do so since you need to define sufficient external <i>and</i> internal public APIs and it&#x27;s a significant community effort to standardize these sufficiently so that there is significant chance of re-use.<p>But at least it&#x27;s a way forward. Fight the heavy module trees. Let&#x27;s use some higher order reusability.
评论 #9731868 未加载
sbovalmost 10 years ago
I generally agree with this. However, sometimes using a module is not adding a dependency, it is making an already existing implicit dependency explicit.<p>E.g. we have client and server code. Serialization configuration between the two is implicitly dependent upon each other - if the client expects dates in a different format than the server, things don&#x27;t work. To make that implicit dependency explicit, we use a module, which also has the affect of making sure the two don&#x27;t get out of synch.
tempodoxalmost 10 years ago
A very good article that aptly shows (some of) the hard &amp; sticky questions we are confronted with all the time. How you answer these questions will determine the quality &amp; stability of your code to a large extent.<p>I agree with the OP that commonly, “<i>dependencies are worse</i>”. Redundancy will increase the quantity of your code, but dependencies increase its complexity. And quantity is always conquered easier than complexity.
guard-of-terraalmost 10 years ago
This depends greatly on your platform. Java projects accept dependencies much easier than C++ ones because in Java it&#x27;s much harder to cause trouble and also coding styles aren&#x27;t radically different for different dependencies.<p>Perl&amp;Ruby are even more eager, which should be strange since they&#x27;re actually less safe.
评论 #9733101 未加载
rwallacealmost 10 years ago
Excellent article. Just one quibble: he claims a module shouldn&#x27;t be over 30k lines. Counterexamples: Linux, Postgres, Boost, LLVM, V8, all in the million line range. To be sure, each of these has an internal module structure, but that&#x27;s irrelevant from the perspective of someone deciding whether to incur a dependency on one of them - the answer to which may very well be yes because they do enough to make it worthwhile.<p>If anything, larger modules like the ones I listed are more likely to be worth depending on because they do more. It&#x27;s no coincidence that the author chooses command line parsing as a negative example - something trivial enough that the overhead of tracking a dependency may well outweigh the effort of implementing it yourself.
michaelfeathersalmost 10 years ago
It&#x27;s interesting to read this with micro-services in mind.