Coding 2024-04-05
I continued to pick at the scab that is the knot of cyclic dependencies surrounding the matrix module, and I noticed something that I'm not quite sure what to make of it. Let me see if I can explain what's up...
There are four modules that appear to matter here:
- invocation_environment, which defines a class that bundles expressive command-line specifications with the installer metadata required to convert the specifications to a concrete form
- matrix, which defines a bunch of classes, which are responsible for handling axes of variation and instantiating every combination of the relevant axes
- parametric_command, which models command-line specifications at the highest level of abstraction currently used in the project
- artifact, which handles the details of coordinating the prerequisites and outputs of command-line invocations
- dependent_mapping, which is used all over the higher levels of the codebase, but is particularly relevant for the implementation of the matrix classes
Five modules.
invocation_environment has a transitive dependency on dependent_mapping, but doesn't otherwise use any of the other mentioned modules. Both parametric_command and artifact have a runtime dependency on it.
matrix and artifact have a runtime dependency on dependent_mapping.
The other major chain is that, at runtime, artifact depends on both parametric_command and matrix, and parametric_command depends on matrix, and there are additional type-time dependencies, frpm parametric_command to artifact, and matrix to artifact.
The two links that really have my attention right now, for different reasons, are the type-time dependency from matrix to artifact, and the runtime dependency from artifact to parametric_command. This is because breaking the type-time dependency is desirable aesthetically, but I think the natural way to do so would introduce a runtime dependency from parametric_command to artifact, which would be a cycle, unless I can break the existing runtime dependency, and thinking about this highlights the fact that the existing runtime dependency is... strange. artifact just needs one top-level function from parametric_command, and surely this function is doing something that would make it hard to move, right?
Right?
:)
Pause for emphasis.
Well, invocation_environment (remember invocation_environment?) is the only module needed to implement the function. In fact, it's somehow worse than that makes it sound. This function is basically a restricted version of a classmethod from that module.
So, like, should I be trying to break the dependency? Thinking about it, I suppose it comes down to figuring out the semantics. It's a tough hypothetical, because this code seems so... elemental... but I need to figure out which module needs to change if I decide that the behavior relied on by artifact needs to change. The options I see now are:
- Inline the classmethod call in artifact
- Move the function definition to invocation_environment
- Move the function definition to artifact, and reverse the direction of the runtime dependency
I've just put these choices together and I haven't had time to consider them all yet. Hopefully I'll figure something out later. For now, I want to get to sleep.
Good night.