This was a good Christmas. But also, I am utterly wiped out. Let's see what I'm up for.
I was telling my wife about the current state of the project, and I compared it to writing a story in which you're just constantly introducing new shadowy figures which were secretly behind everything all along, including the previous shadowy figures. There's at least a bit more purpose to these abstractions, but it's tiring all the same.
In any case, regardless of whether this layer is the last one, let's get it over with.
The top-level container starts with a Command (probably in the "installer plus string" sense), is followed by any number of type-coordinated Option-producing objects, and has an optional "module" argument which can contain another instance of the overall value, but with any program type.
There are three or four basic possibilities for "Option-producing objects":
- Constant string sequences / environment variables, possibly accompanied by installer requirements. These must contain no IO objects.
- Combinations of ValueAdaptor objects with Dynamic Options that don't involve Output objects.
- Flexible Dynamic objects that create restricted Options that involve Output objects.
- The "or four" comes from, ideally the same flexible Dynamics that create the restricted options can be used to create the ValueAdaptor + Dynamic things, when they're being used for input.
This is going to require a few things. One is that the builder decorators get completely overhauled to create the Output-less Dynamics + ValueAdaptor objects. The other is that the flex methods need to be split up into pairs that have different output types, because now the "Output flex" gets invoked implicitly, but the "Input flex" is invoked more differently and has a different overall purpose.
Here's how I want to lay the groundwork for this:
- Pull the flex methods out into functions.
- Factor out common logic into helper functions.
- See if any of those helper functions should be converted back into methods.
- Split out the input and output code paths, so I end up with four public top-level functions.
- Consider moving most of these functions to their own module.
At this point, I can work on the new types and functions, and updating the existing decorators. At that point, I may put together the basic type helpers I had in mind for helping with the decorators, since I'm going to be messing with the decorators again, and it would be nice to apply a mild level of Don't-Repeat-Yourself to the type annotations.
Anyway, I'm really tired, as previously established, so I'm going to publish this, reflect on these ideas, and ponder some incredibly cursed programming ideas I've been thinking about.