> But I find it hard to believe that among those 10 lines of maths each, there aren't any functions one can extract that form some natural abstraction (e.g. "translate vector" or whatever), so that every handle function ends up being maybe 1 or 2 lines instead of 10.
That's besides the point, isn't it? Just because you can in theory extract functions that doesn't mean you should, or that your codebase will be in a better shape if you do. There's the issue of coupling, and there's the issue of introducing dependencies, and there's the issue of whether the apparent duplication holds the same semantics and behavior across the project. I'm talking about things like does it make sense to change the behavior on all 10 code paths if you need to change it in only two or three? Having a surface-level similarity between code blocks doesn't make them the same behavior, does it?
If you're translating vectors 10 times, or calculating cosines, or whatever, then yes, you should abstract this into separate functions. It's not like "translateVector" or "calculateCosine" are brittle abstractions or anything.
That's besides the point, isn't it? Just because you can in theory extract functions that doesn't mean you should, or that your codebase will be in a better shape if you do. There's the issue of coupling, and there's the issue of introducing dependencies, and there's the issue of whether the apparent duplication holds the same semantics and behavior across the project. I'm talking about things like does it make sense to change the behavior on all 10 code paths if you need to change it in only two or three? Having a surface-level similarity between code blocks doesn't make them the same behavior, does it?