The Intuition Is Because Of Cognitive Load
The intuition against breaking everything or a lot of things down is there for a reason. The reason is clutter. Humans just cannot handle too many heterogenous things.
You said that you worry about too much code, like doubling or tripling your code base. We cannot make much of a difference at cognitive level between 20,000 lines of code and 60,000 lines of code. Both are in category of "too much" for our brains. The only way we can deal with this is looking at a part of it.
Now, if the part you are working on has many small functions then its a lot of cognitive load for your brain. Just by reading names of functions would you be sure enough to use them and take it for granted that they do what their names say without looking at their code? You wouldnt unless you are already familiar with code base - in which case you wouldnt be needing the breakup into small functions because you would be familiar with a medium-sized function as well and quickly go to the part you need to work on - you will go read atleast the code of some of the functions.
People Are Bad In Naming Things
You know people are bad in naming things. Also, code changes and names do not always change with that. Then there are other programmers who may have different mindset. For example, a programmer may be strict about managers and controllers never actually doing anything themselves and always taking work from others. Other programmers may not be strict about it or may be strict about some other idea such as a manager should do one type of work itself too.
Bundling Is Your Friend
What you really need to do is bundle things together. Only then its easy to handle things, not only from above but also from each level of abstraction. Making things too easy at one level necessarily make things harder at other levels.
Having one line functions will result in having too many functions. Bundling them in classes will either result in long classes or too many classes. Bundling classes in namespaces/folders will have same problem though at a lesser degree but now you have an entire new level of abstraction to deal with. Also, you will have to spend a hell lot of time in deciding where to put things, which function to what class, which class to which namespace/folder. The separation is never clean. What if a class has two characteristics?
You need to work on your base. If your base is correct then your entire structure is likely to be correct. You need to use the technology of functions. You have to utilize its benefits.
Statements Are Not Functions
A conditional statement is not a function. Its a statement. A unit of a function. A function is a set of statements. Thats the intention of having the concept of a function in a language. The stack space allocation, the concept of local variables, the facility of returning control to the caller. Use those things.
Use local variables if you want clarity. The declaration and filling of a local variable is one statement or may be two statements if your filling is somewhat complex. It would be a waste to have only that in a function. Waste of your cognitive mindspace.
Functions Are For Doings - Not Just For Preparations
A function is supposed to do something. It has to have some responsibility. Dont think an assembly line worker. Dont make its working as dumb as working of a cog in a big machine. Let it handle some complexity.
For example, its ok if it do null checks on its arguments. Just be consistent about it. Make habit of doing the null checks right before using the arguments. Your function obviously has to use the arguments too, not just do the null checking then pass it on to some other function that actually use the arguments.
Your code is highly testable this way. If arguments arent valid then the function will catch it right at start. It will be the first thing it do. This results in less cognitive load too because you always know that your arguments are clean right before you use them. You do not depend on another piece of code somewhere else to do the checking. Also, you do not have to worry about the function that just used the arguments without checking them to be called from somewhere without the checking.
Do not worry about having the same parameters getting checked by multiple functions. Its a slight waste of computer's resources yes and a good compiler can very well skip that. Computers are made to take that kind of load, you arent. Humans short term memory is many times less in terms of numbers of items than even the registers in a CPU.
Also, its ok for a function to handle multiple paths as long as there arent too many of them. Like both an if and an else path.
A Function Is A Process - Its Supposed To Have Steps
What if you have all of those in a single function? Most of the time you can handle this. Its because you have ability to move on from one part of work to another completely as long as you are sure the part is done correctly. To be sure of that you need to have it in front of you, not somewhere else.
What I mean by above is, once you are done checking arguments for null you can completely move on to using them. You can now for example use them to setup a couple of your local variables. Once done with that you can go on looking at your if part and after that your else part.
You can do all this in one function and it can even be a little larger than your screen size. As long as you arent working on more than 3 arguments, do not have a nested if statement, do not have a triply nested loop you can do it all in one function. The key is to never work on too many things at once, too many arguments or too many local variables; and a clean separation of parts. Its like following a recipee or a script. There is a sequence of steps and its better to have those steps together in a function.
Also, if you are using local variables to do things then use only them, do not use a mixture of local variables and arguments. Look at it as kind of a layer. You may use arguments to fill local variables but then use only the local variables.
Similarity With Waterfall Model
To be clear, the similarity is also with Prototyping Model. Its because the Prototyping Model is nothing but a series of small Waterfall Models. Instead of making the whole project in one go you work in steps and in each step you follow Waterfall Model, analyze, design, implement and the rest.
If you follow the same methodology when writing a function you can have both large and easy to understand functions. Having large and easy to understand functions is good because it prevent clutter and context-switching.
The key is to work in steps. The steps have to be such that once you are done with one you never have to come back to it. This is the essence of Waterfall Model.
An example is a function that generate sql query that fill a grid. There are logical steps in the function.
First there is generation of select clause. Thats where you decide which columns of what tables to show in grid, whether to show them as it is or modify for showing, which columns to auto generate etc. Then you have to make the from clause and deal with joinings of tables. Then the where clause where not only you apply filtering but also do paging. Finally sorting.
The parts are linked ofcourse - thats why they are in same function - but they are cleanly separated. Your paging logic can change independent of your selection logic.
The parts do not have to be independently modifiable. Its just that when you are working on one part you have to not keep in mind the working of another part.
You have to fill a local variable before you can use it, and have a table in from clause before you can select its columns, obviously, but when you are using the local variable you do not have to keep in mind how it was filled, when you are selecting a column you do not have to look at how the joining was done with its table. This is how even in a medium-sized function you can keep cognitive load low.
This cannot be achieved by having multiple small functions because the whole algorithm is not in front of you. You will have cognitive load of context-switching when you go read the bodies of functions or the cognitive load because of worrying that you are doing blind trust (when you aren't familiar of code base, and if you are then you can be of working of this medium-sized function too).