Adding is favoured over subtracting in problem solving
nature.com
nature.com
If removing something, you run into the problem of chesterton's fence: if you don't completely understand why it was there in the first place, you could potentially be messing something up which you do not anticipate. If you have n elements, finding a subtractive solution requires understanding how all of them interact with eachother, which scales like O(n^2). On the other hand an additive solution only requires you to understand your new element and how it affects the system, which scales O(n).
Consider the relative difficulty of removing versus placing a jenga block.
On top of this, think about how complex systems tend to be formed. Typically multiple people each with different needs make proposals and at the end you have a consensus which is, if not ideal, at least acceptable to everyone. Theoretically, if there was unnecessary and harmful stuff in there, either someone would have complained and already gotten it removed or there is some interest group that has a good reason for keeping it there. An addition, on the other hand, may have never been considered the first time around, and can be carefully tailored to minimally influence the status quo beyond the desired change.
That is, it's possible for a small team of experts to keep a piece of software in a constant good, small state by always balancing additive vs subtractive solutions, because everyone has a fairly complete model of the entire project in their head.
But if there is any tendency towards additive solutions (e.g. due to personnel churn, deadline crunch, etc), the project becomes larger and thus harder to keep a model in one's head. This makes subtractive solutions harder to think of and implement, which results in more additive solutions, thus exacerbating the problem.
The gist of it is that when a small team builds a piece of software, they have a theory (or I suppose a mental model by another name) of how it exists (either the literal files on disk or a rough abstraction of the "shape" it takes) and an understanding of the strengths and weaknesses of its design.
One team may share the "theory" of the program with another by adding a new team member, they learn from osmosis (not just the codebase but the insights from other members).
In reality, what often happens is that a team erodes through attrition or even is entirely removed from a project. The new team who takes over it, has no theory of how the software works and has to form an entirely new theory.
That theory may be mismatched to the realities of the environment it lives in (infrastructure assumptions, cultural assumptions and so on) which can make additions even worse.
I suppose I imagine it like the statue of David that gets created in Spongebob only for the weird, out of place squidward nose to be tacked on it like it works but it doesn't seem quite right and you can almost point out the line.
Anyway, it's an interesting conundrum since there's not really an easy way to express this concept to big bloated corporations who think they can just exchange one contracting firm for another, and not end up with a mish mash hell contraption that shits all of their customers.
The natural fix might feel like having sole indies running a project where the mental model is not in jeopardy (sans being hit by a bus) although I would think it's more in the range of 10 people or so but I honestly haven't gotten far enough to test that out yet :)
Additionally, you could say that documenting not just the software itself, but the assumptions held at the time would work. It probably would help but that assumes future developers will read it (some will find a rewrite the only logical course because they don't understand the project, or the language etc) while others may just be under business pressure to "move as fast as possible" which gets mistaken for "writing code" instead of understanding what came before.
Engineers, product managers, executives, and consumers alike probably all _tend_ to have a slight bias towards seeing new features as a good thing, for whatever reason.
And even the second-order perception of that bias ("we should probably consider adding this feature, because I think my manager would prefer that we add more features") probably compounds into this problem.
Prioritizing staying up-to-date, simple, bug-free, and in-line with user requirements might lead to better results; achieving and managing that in practice is a whole separate story.
[1] Footnote: not making any claim about the accuracy of this quote :) But it could illustrate the point somewhat, if the prevalance of the quote has, over the years, led to more sales for IBM.
This of course also applies to multiplication (constructive) vs division (destructive), where division introduces us to the weird concept of infinity when dividing by zero.
And also exponentiation (constructive) and root-taking (destructive), where the latter introduces us to imaginary numbers when taking the root of negative numbers.
- Adding is a repeatable, comfortable process whereas removing tends to require more individual approach.
- Adding tends to be stressed a lot in corporate environment, whereas you don't hear your managers demanding to remove features.
- Adding is usually easier to explain whereas explaining how removing functionality improves the system requires more effort on both sides.
- Most people treat code as asset. Which is completely backwards way to think about it. I think about the code as liability. If your mental model of code as an equivalent of an asset, the most natural way to improve value of the system is to add more code to it.
- Most techniques you read up on the Internet are aimed at adding brand new code, not at removing it.
People tend to perceive every piece of code as valuable, however useless or stupid it may be, because of the time and money involved.
Until the codebase gets so crippled that you hear the goto solution from these same people : complete rewrite.
I have recently had a potential client come to me to help them rewrite an old Java application. They have already been unsuccessful rewriting it once, now the want "somebody with more experience" to do this "the right way".
So I ask them, "What is wrong with your old app?".
Them: "Let's not focus on it, we are interested in how you plan the new one"
Me: "No, really, I need to know what is the problem with the old app. Please, humor me."
Them: "It is Java 1.6"
Me: "Okay, but what is wrong with the app?"
Them: "We need to upgrade to at least Java 11."
Me: "And how about that app, what is wrong with it?"
Them: "We are being chased by our security for at least past couple years. The problem with the app is that it uses old libraries that cannot be upgraded because of old Java. We tried to upgrade the Java but failed so we want to start with clean slate"
Me: "But what is wrong with the app? I mean... if you have been unsuccessful upgrading Java that surely means there is some kind of underlying structural problem?"
Them: "Yeah, we also have a lot of failed transactions but that is because of old libraries."
Me: "Surely, you don't want to say that back when Java 1.6 was new it was not possible to write reliable applications?"
Them: ...
Me: "Also, why your previous rewrite failed?"
Them: "That's simple, the developers were not up to the task."
Me: "But who managed those developers?"
Them: ...
Me: "That's right. Last question, how did you decide to rewrite the application if you don't know what is the problem with the previous one?"
Them: "What do you mean?"
Me: "No, thank you, I learned everything I needed. Goodbye"
For the former, you have to check your potential addition against all pieces (N checks) or your potential subtraction against all other pieces (N-1 checks). For the latter, you check all potential additions against all pieces (K x N checks) or all potential subtractions against all other pieces (N x N checks).
In your comment, you're comparing checking the viability of a known addition to the entire search for a viable subtraction, ignoring the search for a viable addition.
But to find something to delete — then one needs to know about all existing source code — that takes O(N) to read and think about. (Unless keeps it all in memory)
Meaning, in practice, it's often O(1 * N), versus O(N * N). But yes you're right about the cases when it's a complex thing that can be done in many ways.
Consider a nuclear power plant. While there might be an infinite number of potential safety valves I could add, it won't take me long to figure out one that will be good enough that I can safely add it somewhere without causing problems. Doubling the available valve options does not really make the task harder, but doubling the complexity does mean it takes about two times longer to validate it.
On the other hand if we presuppose that there is one valve in the plant that should be removed, I will on average have to evaluate around half of all the valves before finding it. If you double the number of valves in the plant, now each evaluation is twice as hard, and I will on average have to do twice as many such evaluations, so the task should take about four times as long.
Practically though, there are many contexts where people complain and are ignored.
I think you're over-complicating it; the paper presents easy problems where Chesterton's fence would not be an issue, but upon observing the results they titled it 'People systematically overlook subtractive changes.'
But... without an explicit description of the goals of the structure, you don't know if there's some reason that the roof was supposed to be raised. An additive solution is less risky, essentially, and can be implemented in the face of incomplete knowledge. That's Chesterton's fence in a nutshell.
In this structure, a roof is supported by a pillar at one corner of a building. When a brick is placed on top, the roof will collapse onto the figurine. Adams et al. asked study participants to stabilize the structure so that it would support the brick above the figurine, and analysed the ways in which participants solved the problem.
And in more detail from the notes on the original paper:
Participants could stabilize the top platform of the Lego structure so it could hold a masonry brick above the head of the action figure by adding new supports to reinforce the single corner block or by removing the corner block and letting the platform sit flush on the layer below. They earned $1 for successful completion, but adding Lego bricks cost money. The most profitable solution was to remove the single support. Participants were randomly assigned to instructions that explicitly stated ‘removing pieces is free’ (cue condition) or instructions that did not mention removing pieces (control condition).
It seems to me the problem to be solved was clearly stated (in the supplementary material, it is even more clear that the reference to a 'masonry brick' is an actual terracotta brick weighing ~3lbs, not an additional lego brick); the specific result was that In the control condition, 41% produced a subtractive transformation and in the subtraction-cue condition 61% produced a subtractive transformation; but a follow-up experiment involving reviews of possible solutions shows they were perceived as equally valid (also in the SM).
I guess it's possible that what's being measured here is confused by a variable of whether people take things at face value, or assume 'there must be more to this even if not stated,' but even when told that removing bricks is acceptable, 40% of people choose not to.
When I saw the problem description, my natural inclination was to add a support brick in a way that doesn't stick out, to stabilize roof in that direction without altering the building's appearance from both ground level (how the action figures would see it) and air level (how a human would see it). Remove that main pillar instead, and the building is now a meaningfully different one. Additive solution feels much less invasive, and it's something I'd default for in real life, on the assumption the original architects / owners liked the existing looks, and would prefer it not to be visibly altered.
Of course, I then thought, "since looks are technically not a part of the problem definition, I could solve it by removing the middle brick" - but that's my software engineering experience kicking in. The way this thought feels is the same as if I discovered a neat work-minimizing hack when writing code, or in general, how I feel when solving logic puzzles. But in logic puzzles, I already know the whole point is to find the solutions that feel clever.
I think people do have some natural, subconscious intuition for Chesterton's fence - for minimizing unknown unknowns. And to shut it off, it takes more than just saying "removing bricks are allowed", you need to convince them to switch their thinking into puzzle mode, make them explicitly discount the solutions that feel obvious.
So I'll revise my position to: based on my personal experience, observing people I know and general impression I get from reading and hearing things, I believe there is a non-trivial subset of the population, of which I'm a member, that has a sort of subconscious intuition for Chesterton's fence, and do not, by default, take problems at face value.
By the way I think you might find this paper of interest - about social dilemmas rather than cognitive styles, but I wonder if the results might not be rooted in the same sort of implicit assumption/intuition that you're positing.
You seem to be claiming that you believe these two actions (subtracting and adding) are theoretically of equal difficulty - but in practice, they are not equally difficult.
It's far more common, almost to the point of certainty, that you will lose by removing an existing block. You are vastly more constrained in your actions when removing blocks that are already placed.
Adding a piece has no feedback. If you slightly nudge the tower while placing the piece, it could very easily topple then and there. You have to judge where to place the piece, and commit to it, without any room to finesse the placement if something goes wrong.
Anecdotally, all my Jenga losses have been when I was too stubborn with a pull, or when I simply misjudged a placement.
Beyond the immediate analogy, I don't think Jenga really matches with software development. In Jenga, the material you have to work with is fixed, and you must always move material rather than truly adding or removing over time. (And a Jenga game is designed to end in failure, unlike (or is it?) software engineering.)
If you look at something like a sand pile, where you're always adding grains, you'll find irregular but predictable catastrophes as the structure fails.
To remove, you must be sure you know the full interaction graph it already has.
I encounter this in code all the time. I'm currently dealing with a support case where I tried to remove ~10 lines of code, and wouldn't you know it, it's causing issues. By contrast I add lines of code by the hundreds all the time with virtually no issues.
Jenga's only a metaphor, don't too caught up in it. Most human-designed systems don't have dependency graphs that look like that. Ugly ones, sure, ones that don't match the pretty diagrams, sure, but we don't generally build systems where literally everything critically depends on everything else, if for no other reason than we aren't good enough to build that sort of system without it coming down around our ears almost immediately. We have to have some degree of isolation.
(There are multiple places where for simplicity I'm not adding caveats, like, obviously I can't always add 100s of lines with no issues.)
Subtractive, you need to do that same analysis for every part of the system you could potentially remove, so you're doing n operations n times each. The subtractive analysis only becomes equivalent to the additive one if you know a priori which specific element you ought to remove.
Placing a jenga block, you can choose to put it in a location that is relatively easy to analyze, for example the middle of the next layer up. Removing a jenga block, you first need to decide on which block to remove, and then you have to deal with the situation it actually happens to be in. Either action could knock the tower over, but the odds of you getting something wrong go up dramatically during the removal phase.
* Infinitesimal differences or to the derivatives of functions in calculus, differential geometry, algebraic geometry and algebraic topology.
* General relativity with it's underlying differential geometry and differential topology for manifolds, pullbacks and covariant derivatives or differentials of vector fields and tensor fields
* Difference in differences between treatment group versus a control group
I couldn't imagine what our understanding of the world would be like without subtractive solutions.
It may be easy to convince most people that a farm subsidy is doing more harm than good, but it's hard to convince the farmers that there aren't any other subsidies that could be cut instead.
To make the situations comparable, if you're adding something, you should have to convince the N people that there are no better things to add. The same as your suggestion that they would need to accept that the removal of a particular thing is preferable to all other possible things that could be removed.
In fact, it seems easier to remove something since there are only the things that people have already agreed on. To add something it could be compared to a world of possibilities which might be better.
Oh ... I guess it may all boil down to bijective systems
I think there is probably a huge social component. Leaving existing stuff alone and adding something will get a lot less push back than removing something.
It is also a risk averse solution. You have to understand a problem space fairly well and be confident you are correct in order to effectively cut and have any hope that people will generally be happy with the outcome.
It can be done, but it tends to be a lot harder.
So it is also something we are simply inculcated with because adding stuff is the thing we experience the most often as the way things get handled.
> [T]he principle that reforms should not be made until the reasoning behind the existing state of affairs is understood.
If removing things is allowed, it would be just as valid to take the roof off of the structure entirely, or to demolish everything underneath it and just leave the slab on the ground.Another way to look at it is that adding things has a known cost in this experiment, but presumably any cost of removing something is not mentioned. If adding three pillars costs 30 cents, and removing one pillar has non-zero, unknown cost, which one would you choose?
Remove all the marble that isn't part of the statue.
> Given the benefits of balance bikes, why did it take so long for them to replace training wheels?
Answer: because buying a dedicated bike just to train how to use a bike is not something you can do unless you're affluent. Adding or removing training wheels is cheap and means you can keep using the same bike.
find a reasonable long grass hill - not to too steep, but steep enough to allow a kid to go down the hill riding the bike with out pedalling.
and then goto the top of the hill and let them go down the hill on the bike. Once they master the balancing part of going down, they seem to pick up the art of turning the pedals at the end of the hill to keep going (if not, explain what to do)
advantages: doesn't hurt when they fall off, gets them used to rough terrain. it becomes fun once they start to master the balancing bit
We had been trying for weeks without result, both with trainer wheels and to run behind with an attached handle. Then one day we unmounted the pedals and lowered the seat... after just an afternoon we could reattach the pedals and he was now cycling on his own!
I'm really not understanding why you think it's necessary to remove more than that.
I've done it on quite a number of different bikes, it really is quite easy.
I have no idea how these victorian steam punk contraptions are assembled and sold at a <$100 price point
I'd really like to see training wheels with adjustable spring tension. Gradually make the spring weaker so the training wheels have less effect every couple weeks, until they aren't really doing anything at all.
Also I'm talking about the training wheels being lifted an inch or two. Causes a lean of maybe 10 - 15 degrees I'd guess.
That is where I was hoping to find spring loaded training wheels so that it forces the kid to constantly try to balance. Start off with really stiff springs and then weaken them over time.
It only took a couple hours with each kid... pushing them up to speed and then letting go. They’d fall, there would be tears, and we’d try it again. And, then, after several scraped knees and bruised shins, that magical moment would occur when some little cluster of neurons finally makes the new connections, and voila... they’d be bike riders. All the tears and frustration would be replaced by euphoria.
Clearly a two or three year old, perhaps, is better off with a scooter or balance bike. But, as an old fart, watching 7 and 8 year olds in the park riding ‘balance bikes’, I get the sneaking suspicion that the parents are stretching out a couple-hour process to a couple-month or year process merely because they can’t permit themselves to let the kid wipe out.
Don’t even get me started with swimming...
Taking the pedals off seemed functional equivalent to a balance bike, and I taught my 4 and 5 year old to ride their bikes the same afternoon.
Same with swimming.
It's kinda goody to judge other parents, tho. A lot of stuff that is easy for me is hard for other folks. But I've been divorced twice, and a lot of folks haven't. So very difficult to judge.
I don't, in general, think that your description of why folks aren't teaching the kiddos using your method is accurate. IME, most folks are just ignorant that it can be done at all.
But, getting back to the article, I’m somewhat dubious about the assumption that humanity just stumbled upon the idea of a balance-bike due to some mental fog that prevented us from considering it.
I think it might be more likely that parenting-styles have changed a bit and there is now a market for a bike-teaching tool that is safer. In other words, I suspect that if you presented a dad in the 1950s with a balance bike and explained it was a tool to more gradually and safely get a child pedaling, he might scratch his head and say, “why would I use that? When the kid is old enough to ride a bike, I’ll be able to show him how in a single afternoon.”
Training wheels make a bike rideable very quickly.
What got them riding without training wheels was learning to ride Razor scooters. One afternoon when I saw them both riding sweeping S curves on their scooters, I took their training wheels off. At 6 and 7 1/2 yrs, they when from total terror on their bikes to riding comfortably in a few hours. It only took a few rides with me running alongside holding on (continually holding on less each time).
It was amazing.
(We merged https://news.ycombinator.com/item?id=26740085 hither.)
See C++ and most long term software products. I think a difference with software is that when properly designed additive features can lay dormant if unneeded. Not many need Mx-butterfly in emacs, but if you do, it’s there.
Doing that continuously does accrete complexity. But there is often a higher cost to fixing a problem rather than working around it.
Similarly I never try to convince management that I need time to improve code quality... I just do it to code that I’m touching. I think people who don’t know the details have the (often correct) heuristic that work that doesn’t deliver incremental results is just an excuse to waste time / sandbag, so I just don’t bother trying to convince about the ROI.
It definitely makes sense to delete code in some cases, but most of the time the solution requires the addition of code. This makes sense, the size of a program doesn't tend towards zero over time. They tend to grow as new features are necessary and yet the old features can't be retired without causing disruption.
That reality, though, isn't always possible, and software will always trend towards larger line counts and more complexity.
>> Existing code exerts a powerful influence. Its very presence argues that it is both correct and necessary.
It's funny you call yourself "pessimizer", because you seem to be good at optimizing.
We have git! You can get it back anytime you want! Just delete it!
Of course, the niceness only holds if your code is being removed because it is no longer needed. Having your code removed because it doesn't work properly and is being replaced with code that does work properly is not a nice feeling.
I'd prefer to do it right the first time, but given that, I'd prefer somebody make a fix that is shorter rather than one that is larger.
Much easier (or takes less thought, or more easily glosses over important complex unappreciated issues) just to add something that you think will solve the individual problem at hand...
I think all this proves is that if you present people with a partial design that points in one direction, they’ll continue in that direction.
The experiment was run with two groups, both of which were given equal costs on addition – "Each piece that you add costs ten cents". There was also a group given a 'subtraction-cue' where the instructions mentioned that "removing pieces is free and costs nothing". Increase from 41% to 61% use of subtractive method.
There was a cost to addition, so the optimal solution for both groups was removal of the pillar.
For instance do I have to have a roof? Could I just balance the brick on the structure?
Can I remove the whole structure, put the roof on the floor next to the person, and just put the brick on that?
If not, Can the guy lie down to clear extra space so I can remove another layer?
Could I just have the guy lie down and surround him with one layer of bricks and then put the roof on that?
It’s not immediately obvious to me that all the above solutions would be allowed as an answer, because the question is to put a brick on “the structure”, so surely if I remove some of “the structure” then that’s hardly putting a brick on “the structure”, it’s putting a brick on “a structure”.
I assume by the time you have put the guy in effectively a coffin buried under a brick then someone would argue that the purpose of the structure is lost, but you could also argue that somewhat if you removed the roof height (a higher roof could be a feature).
Look at the last paragraph:
> policymakers and organizational leaders could explicitly solicit [...] proposals that reduce rather than add
Their conclusion is that people will add rather than take away, so you should tell people to take away. My conclusion is that people will add rather than take away if not provided enough information about the problem space. I think the solution is to better define the problem, otherwise you can come up with lots of proposals that aren’t suitable.
If I don’t know if making the guy lie down is allowed I’m going to have to make an assumption and either under-optimise or over-optimise.
My view is saying you can remove bricks implies that roof height isn’t important, which changes the users assumption on requirements. The learning should be more clarity on requirements, rather than just “ask people to reduce rather than increase”.
Additionally, if you changed the rule and said “participants will be scored based on the number of blocks removed”, I assume you would also get people creating silly scenarios like the ones I described and wholly unsuitable designs. This is more realistic in the real world where less material = less cost.
Also in personal experience as an engineer working with architects, suggestions to make radical alterations to the form of the structure are usually not well received...
It's not an unreasonable assumption to make. Like if you present someone with the sequence "1, 2, 3..." and ask them to continue it, they're going to say "4". It doesn't prove anything to say "Aha! The sequence was actually "1, 2, 3, 2, 1 behold your preference to add rather than subtract!"
# rant over
It was absolutely fantastic when I understood how to first write the code, and then design it!
Sounds like the SAFe people left that part out.
https://www.folklore.org/StoryView.py?story=Negative_2000_Li...
Subtraction increases chances of breakage.
This approach increases maintenance costs (duh) but form customers PoV, it's better if something I rely on doesn't stop doing it.
Everyone agrees if you say "complexity is bad for security". But somehow it's still incredibly unpopular in practice. Most commercial security products are all about adding more stuff, and they don't seem to go bankrupt.
I work in the mechanical design space and definitely solve problems with additive and subtractive solutions all the time, and it depends a lot on the context of the solution. This thinking almost certainly continues to other problems that I encounter in everyday lift.
Machining, for example, is subtractive by nature, so initial solutions to a problem are usually additive since it costs money to subtract more, but something already made tends to be subtractive as you can't easily add material back.
Conversely, for molded/cast parts, your design is initially subtractive as you want to use as little material as possible, but after the part is tooled, it becomes significantly more difficult to remove material, where adding material through modifications to the tool are relatively simple. Designing in a "steel safe" condition is a very common tactic for these types of parts.
At the very least I would expect a symmetric experiment where they imply you should be removing bricks and can't add.
-Antoine de Saint-Exupery
This is also relevant: (from my vague memory)
"Any fool can add things. Subtracting, however, requires a genius." - Greek saying
For many decades we have lied to them about how to ride: "steer with the handlebars", a reliable recipe for violent spills.
I tell them to use the handlebars to stay up, and lean to steer. Off they go! It is amazing to see, every time.
This is to the extent that many integrated circuits that drive external transistors will actually have a charge pump to allow them to generate the voltage greater than the main supply in order to use N over P on the high side. [0] is an example of one I was looking at recently.
It's also tricky to match N and P transistors because there's always tradeoffs on the P side, so if you can just use Ns across the board it can make the analysis component selection easier.
Arguably they are just glanced over because they really do just apply the same principles. I still would reach for a P-channel to do power rail switching on my lower power designs, fwiw, but that's about the only situation.
It seems to be psychologically easier to justify adding things than removing them.
Printing techniques which depend on removing things intaglio is also notoriously hard to learn.
https://www.sciencedaily.com/releases/2021/04/210407135801.h...
https://www.sciencenews.org/article/psychology-numbers-peopl...