Definitely second what Alex said. A guideline i try to use in these cases is to structure things such that when you’re reading the highest-level function, the logic and calls it does express the intent at the highest level, so someone reading that function can gain one level more of understanding of what it actually does, but not more. And then apply that recursively down as well. Often these decisions are also informed by what kind of data or objects need to be passed around between the second-level functions—if you’re just passing tons of data to each one, then it’s not much clearer. Each lower function should have a single purpose and ideally operate on a smaller chunk of the data that the higher-level function knows about.