Okay, I'm still tired, but I'm not in pain any more. I want to get something code-related done. One thing that I've been doing with MOTR, is focusing on new functionality to make writing the motrfile easier. But before I start prototyping that stuff, it might be worth trying to clean up some of the new modules I'm writing. Most of the code I've written is in the motr._api.cli.types module, which is the largest module in the package by statement count, and over twice as large as the next-largest module. Let's see if I can find any points of division.
First, let's see what's in there.
- TypeVar and alias definitions. Some are completely generic, others are specific to the Fragment API, and have some weird decisions. Some of this code should maybe be replaced with an API that's based on subclassing. Which is weird for me to say, but I have good reasons for this very particular case. Some of these aliases seem like they mainly serve to confuse me, and I should try to cut down on them.
- The Installer protocol and supporting types.
- The Key class and supporting aliases and functions.
- The Command class, which brings together the previous two classes. And a bunch of aliases that I wonder if there's some more elegant way to deal with. And helper functions that convert between those aliases as needed.
- The Registry Protocols (which are used by the helper functions). These Protocols are kind of obnoxious, for two reasons. For one, they're all very similar and it feels like I'd be able to consolidate them with HKTs. For another, once I add enough methods, PMaps stop satisfying them, but it's weirdly tricky to nail down why. Like, maybe there are sets of three methods, where I can have any two, but if I add all three, it stops type-checking??? I do not understand what is going on. Anyway, there's also a helper method for one kind of Registry in particular.
- Next we get to Fragment API stuff. Starting with CmdMeta, which has methods that call some of the helper functions above, and those functions should probably just be inlined into these methods, which could maybe be properties. Then, we've got the Fragment and Option classes.
- Next up the Builder classes. Builder has some methods that I suspect could be rewritten into some kind of map method, and one that I'm not sure what to do about, the flex method, which is big and complicated, and could probably be simplified somehow. (Like, maybe I can factor things out so it's got a map style method on one side, and a callable on the other.)
- Random helper functions and classes that synthesize the preceding stuff in various manners. Including one helper that works with nothing but basic registries.
- Finally, the helper function that synthesizes stuff from the whole rest of the module into a useful bridge between its high-level representation, and the rest of MOTR's not-quite-as-high-level representation.
Thinking over this, here's a division that I'd like to try making:
- Installer and InstallerRegistry and combine
- Key, new_key, and IterableKeys
- Command and CmdMeta and base_cmd
- ObjectRegistry and ItemRegistry and item_registries
- Fragment and Option and static_option
- Builder and Nullary and static_builder and OutputData
That should properly divide things up so I'm not constantly spelunking in a 600-line file. I'll try and look into this later, when I have a bit more energy. For now, I'll see about getting some energy back.