pass flags as first arg to every function in the code base - too manual
so we could just add that map as the first argument to every function, even if the function doesn’t use it yet
When starting the application, near main, I would partially apply all functions with the feature flags that are relevant to them. Callers of those functions would receive the already partially applied functions as parameters.
Granted, this would still have a whole lot of parameter-passing. But receiving your direct dependencies as parameters is less dispiriting than receiving some feature flag value that you don’t use directly and it’s only required by the implementation of some dependency far below.
The initial “wiring” of the functions could be done manually, or we could make use of some dependency injection helper library like “registry”.
Edit: about DynFlags in GHC. IIRC, the problem with DynFlags is not really the flags as such, it’s that it’s a monolithic entity containing all the flags that is passed around everywhere, making decoupling difficult because each component is privy to configuration details of other components, and tempted to rely on them, resulting in a big ball of mud. Properly disaggregating DynFlags wouldn’t mean an end to the flags.