I think that if functionality is repeated it makes sense to abstract it into a function. However, I've recently been reading through a codebase in which every function is about 10 lines long, and there are numerous functions that are only used once. This makes it hard for me to follow the code since I frequently need to chase down the 10 line function that is only called once to see what it is doing and then return to wherever I was in the code.
I don't think I agree with that suggestion. That's like saying a table of contents is not useful if don't read a book multiple times. Certainly the DRY principle provides a good prompt of when to abstract code but it's not the only reason to do it.
Usually I am only interested in specific parts at any given time, either because I only have a particular task to accomplish (e.g. update the email template) or because trying to understand everyone at once would overload my little monkey brain.
If I'm trying to just update the email template then I don't care about the part the loads the data and I'd be wasting my time reading it. Sometimes you can't even tell if an chunk of inline code is relevant without spending a decent bit of energy figuring out what it's doing. Having everything in a single function also makes it easier for lines of unrelated code to become entangled together and thus harder to understand.
Well-structured code gives me a choice; I dive in and see the details if I'm interested, or I can leave it for another day and focus my attention elsewhere.
Certainly though, good tools like IDE are vitally helpful in reducing the friction in peeling back the abstractions when necessary. The nature of some languages though means that the level of tool support available can vary widely, which probably has an effect on different prefered coding styles. In Java, for instance, it's pretty easy to find all the pieces of code that call a particular method, while in Python, it's often not really possible without running the code.
With good naming and comments this shouldn't really be an issue. At my most recent software internship I got to see very abstracted code with many short functions, and realized quickly how much more clear to read and maintainable it was.
Yeah, there's ways to screw up every method of coding, but I find favoring more and shorter functions tends to better outcomes. Obviously you could reductio ad absurdum any code into something like:
function do_task() {
do_step1();
do_step2();
do_step3();
}
function do_step {
step1();
}
function do_step2 {
step2();
}
function do_step3 {
step3();
}
But I've rarely seen that be the problem. It's been far, far more common to see giant functions that are much more understandable when broken up.
I agree somewhat, but context switching has non-zero overhead since it requires that I keep in my short term memory what the previous code was doing as well.
Also, I probably should have been clearer above. Sometimes a short function is the right approach, particularly for something that is going to be done over and over again, but the overall goal is clarity, not short functions.
Anyways, it's not worth getting too hung up on I don't think, it seems my opinion is the minority one.