Here is another approach to pass dependencies through deep call stack.
In a couple of words:
- deeply nested code not executes immediately but returns a function for the later lazy evaluation;
- the correponding function accepts the required environment;
- at the top level call the function returned from the nested code and pass the environment to it. Documentation.