Live data from Hacker News

Never edit a method, always rewrite it?

dave.cheney.net

81–90 of 120 posts

Re: Never edit a method, always rewrite it?

#81

It has been my experience that after a substantial period of being in real use, methods embody tacit knowledge about the problem domain that isn't necessarily evident from their public interface. Because initially they didn't embody that, and it caused bugs, so people edited in fixes. It has been my experience that rewrites from scratch typically lose all this tacit knowledge and re-implement the original bugs.

You're not wrong.

In theory if every time a fix was implemented, a corresponding unit test was created then you should be able to adequately test the rewritten method.

I say in theory though because that never happens.

Re: Never edit a method, always rewrite it?

#82
post #61

Earlier quoted context omitted.

I'm not convinced of the "always rewrite" thing, but what you're talking about would be solved by writing tests when you fix a bug.

It's not the first time someone proposes to write a test when fixing a bug, but you have to question the actual ROI. At my previous job, they checked how likely it is for a fixed bug to reappear again. Odds are really low. So we decided it wasn't worth the investment to write a test specific for the bugs use-case, because it's unlikely to appear again. We focused our efforts to other, more effective things.

Were you writing tests before? It could be that writing the test was causing the original bug to be fixed properly and prevented it from showing up again.

Re: Never edit a method, always rewrite it?

#83

Earlier quoted context omitted.

We use the test as a way to prove we know what the bug actually is. Our debugging "path" normally is: 1. Find out bug exists 2. Write a test that can reproduce the bug 3. Distill that test down to the minimum needed 4. Fix bug until test passes 5. Test bug is actually fixed by trying to reproduce it the same way the user/bugreport did. When done like that, the test isn't "extra work" but is just part of narrowing dow…

Whist I agree with this approach, sometimes it just isn't possible if the code was written in a non-testable way to begin with. Such as code that hits the database a lot or relies on network data. In this case, weighing up the ROI is a worthwhile endeavour, with a note to refactor more thoroughly at a later date.

That's a really good reason to write business logic in a way that doesn't have those dependencies hard wired in. I often end up in those sorts of nightmares in codebases that use the active record pattern (hiding database access everywhere), hooks, critical logic in the HTTP layer, and so on.

Re: Never edit a method, always rewrite it?

#84

It has been my experience that after a substantial period of being in real use, methods embody tacit knowledge about the problem domain that isn't necessarily evident from their public interface. Because initially they didn't embody that, and it caused bugs, so people edited in fixes. It has been my experience that rewrites from scratch typically lose all this tacit knowledge and re-implement the original bugs.

You're not wrong. In theory if every time a fix was implemented, a corresponding unit test was created then you should be able to adequately test the rewritten method. I say in theory though because that never happens.

Unit tests can only test certain kinds of behavior of the function under test. To give other kinds of examples, the current implementation might have used a clever trick to achieve faster execution (this cannot be evaluated with unit tests). Alternately, it might have been implemented so as to share common functionality with a different piece of code by calling a common subroutine. That sharing of functionality is probably not easy to evaluate with a unit test (nor is it wise), but is still an important property to preserve.

Re: Never edit a method, always rewrite it?

#85

It has been my experience that after a substantial period of being in real use, methods embody tacit knowledge about the problem domain that isn't necessarily evident from their public interface. Because initially they didn't embody that, and it caused bugs, so people edited in fixes. It has been my experience that rewrites from scratch typically lose all this tacit knowledge and re-implement the original bugs.

I’ve seen this in two broad circumstances: complex business rules, and spaghetti code. Business rules mostly have to be endured. Spaghetti code should be untangled if the software is still actively developed. This caveat appears much less often in editors, design applications, general horizontal apps and games. Those are more likely to suffer from poor design or coding, and the spec is much more in the control of the software people.

Re: Never edit a method, always rewrite it?

#87
post #84

Earlier quoted context omitted.

You're not wrong. In theory if every time a fix was implemented, a corresponding unit test was created then you should be able to adequately test the rewritten method. I say in theory though because that never happens.

Unit tests can only test certain kinds of behavior of the function under test. To give other kinds of examples, the current implementation might have used a clever trick to achieve faster execution (this cannot be evaluated with unit tests). Alternately, it might have been implemented so as to share common functionality with a different piece of code by calling a common subroutine. That sharing of functionality is pr…

The most "fun" subcategory of "how do I write a test for this?" that I've seen is when something in your software triggers a bug in somebody else's product, and "somebody else" is both too big and important to return your calls and too relied-upon for the bug to go unaddressed (e.g. the Oracles and Ciscos of the world). So you have little recourse beyond screwing around with your code until the user stops seeing the bug.

Re: Never edit a method, always rewrite it?

#88
post #84

Earlier quoted context omitted.

You're not wrong. In theory if every time a fix was implemented, a corresponding unit test was created then you should be able to adequately test the rewritten method. I say in theory though because that never happens.

Unit tests can only test certain kinds of behavior of the function under test. To give other kinds of examples, the current implementation might have used a clever trick to achieve faster execution (this cannot be evaluated with unit tests). Alternately, it might have been implemented so as to share common functionality with a different piece of code by calling a common subroutine. That sharing of functionality is pr…

> the current implementation might have used a clever trick to achieve faster execution (this cannot be evaluated with unit tests).

Sure it can. I worked on a project with a pubic API with many time sensitive routines and we most definitely had unit tests measuring performance. The test failed if the execution time exceeded the acceptable threshold.

> Alternately, it might have been implemented so as to share common functionality with a different piece of code by calling a common subroutine.

You can certainly write coherency tests to ensure that two methods are doing what's expected. They might not share the same subroutine any longer but you can throw an exception when their respective results no longer align and have comments on the test explaining the rationale. Honestly if you have this sort of subtle dependency and you don't have a unit test for it then you're just asking for trouble.

Re: Never edit a method, always rewrite it?

#89

I've been doing something similar. I name the new method Method, rename the old one as MethodOld and in Method, before the return value, I put an assert(MethodOld(args) == return value). It's one of the things that when I do, I appreciate the value of, but I'm not disciplined enough to do as much as I would like to lol.

It would be nice if our language/tooling/runtimes could assist in this. Same thing for version diversity in microservices.
Post reply on HN