Open mppf opened 7 years ago
Would support for private fields help at all, or was that just an example of the general problem?
My initial instinct is to try and keep this simple, and that we should generate the naive writeThis that prints the first example. I feel like the nested nature of {super = { super = { ... } } }
isn't human-friendly, but perhaps that's not the point.
It was just an example of a general problem. The point is that the child class shouldn't necessarily know about all of the parent class fields and in fact the parent class should be able to control which of them print.
The "shouldn't necessarily know about all of the parent class fields" point still feels to me like something that should be controlled by language visibility constructs.
Approaching this from a different angle, it's possible a class could have all private fields and a custom writeThis. If a child class' writeThis ignored private fields, then we'd end up not printing any information about the parent. That doesn't seem like good default behavior.
I guess I'd be more open to the "super = {}" approach if it spanned multiple lines:
Child {
super : Parent = {parentField = 0}
childField = 0
}
But that may lead into issues with whitespace alignment and brace styles...
I think that one of two things should happen here:
1) the presence of a parent class writeThis()
routine prevents the compiler from generating a default writeThis()
routine on the child class, and if the child class doesn't have an explicit override, it simply invokes the parent class version as with any other inherited method (i.e., if the child class wants to specialize its output beyond what the parent would do, it has to do so).
2) the presence of a parent class writeThis()
routine causes the compiler to generate a default writeThis()
for the child that invokes the parent class writeThis()
before writing out the child-specific fields in something like the usual way.
My intuition would be to do option 1 here because it seems simplest and consistent with how other dynamically dispatched, partially overridden methods behave.
Option 2 might seem "more productive" in some way, but it's also problematic as Michael notes above, due to questions like "where do the curly brackets go?" I also think that there's an argument that if the parent class really wants to specialize its output, it seems unlikely that the child class would not want to as well (i.e., that any compiler-generated default would do something that was more reasonable than surprising).
PR #16920 adds some futures around this topic.
There are some problems with the current
writeThis
strategy when combined with class inheritance.Right now, buildDefaultFunctions constructs a
writeThis
for any type that doesn't have awriteThis
or areadThis
method. The trouble is, a parent class might have such a method and buildDefaultFunctions does not notice that.Consider this example:
This program prints out
In this case, the author of Parent wants to hide a field from the I/O. But, more generally, how can the author of Parent write a custom writeThis that has any impact on subclasses?
It seems tempting to have buildDefaultFunctions generate Child.writeThis in a way as to call Parent.writeThis. However, that strategy isn't compatible with the current formatting for classes, namely that the child class, when output, includes a mix of parent and child field names. We could address that by outputting in a different format, like this (when outputing a Child above):
(But I am also always wondering if we should include the class type name in such output).