Still very much a work in progress. The pickler stuff will eventually get split out into another library since very little of it is specific to java, but I'm keeping it in here until I'm more satisfied with it.
Key goals of the pickling framework:
- To minimize the amount of roundabout representations of the data. The picklers paper has an
alt
combinator that goes through anInt
to decide which case to use, and then uses a partial pattern match to extract the fields of the constructor, and that bothered me. Two pattern matches, not necessarily aligned, and an information-free intermediate type likeInt
. Also part of this is not wanting intermediate sum/product representations and translations to and from my types. - At least in principle, it should be as fast as possible. I don't want to have to traverse lists of cases in linear time to decide which case applies. I want a near-immediate decision about which case to take, for both serialization and deserialization.
- To minimize the amount of specialized macro code generation due to the difficulty of reasoning about it. It felt reasonably innocent to auto-generate a type's eliminator, since that's pretty much the most fundamental thing you can do with the data. Everything else stems from that.
- To have a pleasant syntax for defining large sums of products. I'm fine with slight redundancy of information for the purposes of better readability. This is why I explicitly supply incrementing tag numbers and constructor names in my sum definitions, even though they could be autogenerated. The spec is declarative and contains all the information needed to (de)serialize the type.
Ongoing goals:
- Support context-aware combinators rather than the prebuilt ones I'm including now. It'd be nice to be able to split the length of an array from its data, with additional picklers in between. This is a hard problem.
- State-aware combinators for deduplication of values.
- Minimize amount of type-level nonsense. I fail miserably at that right now.
- Make the whole thing more modular/composable. Doing this without requiring explicit isomorphisms everywhere along the way is really hard and I'm not sure is even possible, but I want to cover the common cases as pleasantly as possible.