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.