Протаскивание аргументов через цепочку функций

Один из нюансов функционального программирования в том, что всю информацию о внешнем мире функция получает через свои аргументы. Чего нет в аргументах, того нет вообще. Такой подход уменьшает число ошибок связанных с глобальными переменными. Такие функции легче тестировать, потому что все их зависимости передаются в функцию через аргументы и не нужно создавать какую-то внешнюю среду для функции.

При написании функций, часто бывает такая ситуация, что приходится протаскивать какой-то аргумент через несколько функций верхнего уровня до конечной функции.

foo2(arg);

function foo2(param) {
    foo3(param);
}

function foo3(param) {
    foo4(param);
}

Мне кажется, что это ошибка проектирования и связана она с тем, что не происходит возврата значения наверх из глубинных функций. Если функция foo4 располагает какими-то данными, сложив которые с аргументом arg надо произвести над всем этим какую-то операцию, то тащить в функцию foo4 аргумент arg неправильно. Нужно наоборот через return обеспечить всплытие данных foo4 наверх, и там наверху сложив их с arg сделать нужную операцию.

foo2_res = foo2();
doSomething(arg, foo2_res.foo3_res.foo4_res)

function foo2() {
    return { foo3_res: foo3() };
}

function foo3() {
    return { foo4_res: foo4() };
}

Протаскивая через функцию косвенные аргументы, вы размываете фокус и специализацию этой функции. Т.е. она размывается и теряет свое узкое назначение.