3 ms·
> Far too many times I’ve seen code that looks mostly the same try to get abstracted out into a “re-usable” class. I’ve had a hard time explaining this but I k
by Waterluvian 3y ago
> Far too many times I’ve seen code that looks mostly the same try to get abstracted out into a “re-usable” class.
I’ve had a hard time explaining this but I know it when I see it. Two things that are the same shape but aren’t really semantically related. So if you try to share code, your abstraction breaks the moment they start to inevitably express how they’re not related.
- Maxatar 3y agoSure, if the abstraction is very broad like a class, but I find I have a lot of success factoring out code that mostly looks the same into a plain function.
- piva00 3y agoSure, and as usual nuance needs to be applied. I've seen these refactorings also break at some point over time, after the function needs to be expanded and delegate to other functions when extended, ending up in a 3-5 layer of function delegation that just makes me angry to read because it's stupid cognitive load to follow a dead simple code path. It's never that cut and dry, there's always nuance to almost every pattern we try to apply in code.
- Maxatar 3y agoThat sounds like a different problem. There is a difference between taking duplicated code and eliminating that duplication by using a function, and having a short function that calls another tiny function that in turn calls yet another tiny function when all of these tiny functions can just be merged together... The problem you're mentioning can happen regardless of whether someone repeats the same thing everywhere, or whether someone factors out common code into a single function. John Carmack wrote an article [1] about the point you bring up, and how humans can understand a certain degree of complexity more than they can understand a very tiny amount of complexity or too much complexity. There is a sweet spot when it comes to function call length, not too long, not too short. But once again this is a different matter altogether. [1] http://number-none.com/blow/blog/programming/2014/09/26/carmack-on-inlined-code.html http://number-none.com/blow/blog/programming/2014/09/26/carm...
- piva00 3y agoThat's exactly what I meant by nuance, because the refactor into a function could never predict that 6 months down the line that specific function needs to be expanded, and someone might decide to delegate the call to another place. And the mess starts from trying to not repeat some code. Sometimes I avoided extracting a function out of some duplicated code because I intuitively saw that they had some potential divergence down the line, and it has paid off quite a few times. That's part of the problem as well, it depends on wisdom and intuition only gained through experience.
- Maxatar 3y agoSo expand upon it, functions trivially compose unlike classes. There is nothing about deduplicating a function that prevents you from diverging from it later on. There could be some judgement calls and technical expertise needed to determine the right amount of parameterization of a function, but I'm not sure I follow the idea that a simple function, which is nothing more than a "name(parameters...)" that needs to be changed 6 months down the line is somehow causing a giant mess. If anything, the benefit of deduplicating is that if you find there is a bug in your implementation, or an optimization, you can fix the bug or apply the optimization in one place and get the benefit at multiple call sites, as opposed to having to go to a bunch of places. With that said, it's not my position to tell you not to repeat yourself. If you find repeating code helps you for whatever reason, go for it. I'm just saying that it's perfectly fine for developers to avoid repeating themselves by using functions and their code won't become a giant mess as you seem to indicate it will. Functions are very simple, flexible, and elegant abstractions for code reuse and even if you somehow found that you had to eliminate a function and repeat it in multiple places, that's a trivial operation to perform that most IDEs can do, so it's not like you're locked into this. The same can not be said if you use a class as a way to avoid repetition.
- Waterluvian 3y agoThe way I’ve seen this failure expressed is when a handful of helper functions gain a bunch of optional arguments to toggle behaviour that most of the callers don’t care about.
- Maxatar 3y agoSure, people can write bad functions, I'll never disagree with that. I tend not avoid allowing what bad programmers do dictate how I or people on my team write code.
- jandrewrogers 3y agoThese cases are almost always an example of convergent evolution as in biology. Common environmental constraints drive them toward the same shape and behavior but their DNA is fundamentally different. As soon as the constraints weaken or change, they diverge again to reflect their underlying DNA.
- Waterluvian 3y agoOh no. Are we talking diamond-shaped inheritance… in real life?!
- drewcoo 3y agoIf it walks like a crab . . .