-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kinded union gen #64
Kinded union gen #64
Conversation
So far, the generation itself runs, but the result will not yet compile. I just want a checkpoint here. (Most of this was written a few days ago already.)
…ors. This template munging business got nastier as time proceded. I think we could drastically reduce the amount of redundancy in the arugments to `kindedUnionNodeMethodTemplateMunge` if we re-did that function with a more structural understanding of what's going on, and made some basic understanding of what zero values are per golang type, etc. That can be future work, though. Today, I want working kinded unions, and I just want them done enough to use; kludge tolerance high.
The AssignNode method is now supplied; and the previous hacky shrug regarding switch statements with no applicable cases also had to go. (Turns out that the no-applicable-cases thing coincidentally worked for the "embedall" internal implementation mode; but didn't fly for the "interface" internal style, because that would end up with variable declarations made but not referenced. Harrumph.)
"textual concatenation of template strings" - i.e. the Re "behavior", it seems to me that this is just a synonym for "representation kind". Is it only introduced here because there's no way to publicly access the |
Yeah, some sort of method is needed on the interface because I didn't want to destructure my way into each RepresentationStrategy -- mind, there's no single RepresentationStrategy interface at all; it's just a convention of things -- and attach the property there. There's no way to get a RepresentationStrategy from a Type in general. I guess adding a RepresentationStrategy interface would've also been a valid way through this. It didn't really occur to me, because this is the first time that we've needed the same property from each one of them. So far, everything else has required destructuring because things have been full of unique behavior per strategy. I'd be open to revisiting this.
|
good thing you already have |
Yeah... I feel kind of sketched out by that constant, honestly; there's times where it's a valid sentinel (okay, one time: this, here), and many times where it's not (and I just marked it explicitly so that the appearance of 'zero' value clearly means an uninitialized structure was found and that it's a bug). But doing something safer in golang would require about a hundred lines more boilerplate than currently seems justifiable. |
Kinded unions are now generateable!
My favorite part of the diff is quite simply the feature table change:
Kinded unions are pretty neat to have, because between them and keyed unions, we can do most of the stuff that's Interesting. (Substituting keyed unions for other strategies as a placeholder during prototyping systems is generally fine (in addition to the fact we simply use them the most in new designs anyway); kinded unions less so, because they change the topology of the document rather noticeably.) I've started prototyping a bunch of stuff using them.
It has turned out we can also now generate any "Any" type using kinded unions and really no additional special effort at all, which is pretty neato:
... will result in codegen of a perfectly reasonable compact little structure:
Something like this will probably end up in the "prelude" of default types in a schema.
(The types named
Map
andList
here aretype Map {String:nullable Any}
andtype List [nullable Any]
, which is a fun cycle, but turns out to fly right, and still leaves us with a self-contained "prelude".)Alternately, if the adjunct config contains
CfgUnionMemlayout: map[schema.TypeName]string{"Any": "interface"},
, then you'll get:Implementing this was a bit more of a bear than other things: the representation types for kinded unions don't get to use any of the other helpers and mixins we've made for all the other systems, because they don't consistently behave like any single particular kind! So, lots of stuff that would've been taken care of by one of the mixins in any of the other representations we've coded up so far end up being a bit more manual and unique here.
The
schema.Type
interface also sprouted a new method:RepresentationBehavior()
, which says what a type's representation mode acts like. It's necessary for the codegen code to look at this information on the member types of a kinded union when making some choices for its internals.I used a different kind of code reuse in the course of this: textual concatenation of template segments. Seemed like as good a time as any to try it out as a style, since the mixins pattern was inapplicable anyway. It... well, it works. I don't think it turned out particularly well, though. I'm okay enough with it to merge it for now, but in the future it might be preferable to avoid this style of writing; or at the very least, make the parameters themselves be something with a more logical understanding of things, rather than being template snippets. (The number of template snippets needed to complete the task grew a lot faster than I expected; you can see the progress from "this is fine" to "ugh" in the procession of commits in the PR if you're interested in the evolutionary record.)
A new document of
HACKME_dry.md
, with remarks on the various mechanisms for "don't repeat yourself" used in the codegen system, has appeared, incidentally.There are a few bugs I've found as I've tried to exercise this in downstream prototypes. However, I don't think they're due to the code that's new in this PR (and I'm just finding them because I'm doing larger and larger prototype usage); so, I'm going to merge this, and then chase reproducers and tests for those bugs, and then their fixes, in separate branches subsequently to keep things readable.