I wonder if there is common pattern in functional programming which overcomes this problem. Two possibilities come into my mind:
Put all configuration variables in a configuration type with several subtypes and only pass this config type to the function:
immutable Filter1
cfg1::Float64
cfg2::Float64
end
immutable Filter2
cfg2::Float64
end
immutable Cfg
filter1::Filter1
filter2::Filter2
end
...
filteredValue = function1(someValue, cfg)
finalValue = function2(filteredValue, cfg)
However in this case the function has to know the structure of cfg, which is not at all ideal.
The other method that comes into my mind is:
Put all configuration values in a type as shown above, but instead of passing that to the function itself, create an extra function, which initilizes the function in need using closures:
function initFilter1(cfg)
return X -> function1(X, cfg.filter1.cfg1, cfg.filter1.cfg2, cfg.filter2.cfg3)
end
function initFilter2(cfg)
return X -> function2(X, cfg.filter1.cfg1, cfg.filter1.cfg2, cfg.filter1.cfg3, cfg.filter2.cfg4)
end
...
filter1 = initFilter1(cfg)
filter2 = initFilter2(cfg)
filteredValue = filter1(someValue)
finalValue = filter2(filteredValue)
The cost of this method is the additional function that is needed for every function with a long list of arguments. Is this a common pattern in functional programming?
Are there other patterns?
In my case the Config type holds a lot of different types. Only a small part of the large configuration is relevant for the specific functions mentioned above. Unfortunately it is not just one subtype which I can pass to these function.
But my real concern with just passing the whole configuration to the function is the seperation of concern principle: Separation of concerns - Wikipedia
What I mean here is that the function should not be concerned about the structure of the configuration variable. If it is, it is much harder to reuse that code in a different context, where I have a different set of configuration names and values, or no Config type at all.
Should note that Dicts are quite slow, and so if you know what the fields will be in advance, you should use a (immutable) type instead. Parameters.jl as mentioned above makes this easy to do. But yes, the choice is really between tuples, types, or Dicts.