fn x() {
doStuff();
moreStuff();
forgotSomething();
}
is pretty bad code, but that's probably because I consider procedures with no arguments and no return value a sign that something is poorly factored. However, fn x(y) {
foo = doStuff(y);
bar = moreStuff(foo);
if (isSomething(bar)) {
return theRest(bar)
} else {
return theBest(bar);
}
}
can be a good way to separate the why from the how and clearly communicate what's going on, especially with conditionals in the mix.It's important, however, that these helper functions are not haphazardly strewn around the code base and accessible to things that don't need them. Depending on the language/context, I'd reach for nested function definitions or public/private keywords (or a combination), because definitely, it can be very hard to approach a big file with a bunch of (often poorly-named) functions that are defined at the same hierarchical level but not meant to be used at the same level.