-
Notifications
You must be signed in to change notification settings - Fork 213
What declaration syntax should structs and extension structs use? #2363
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
Comments
I'll admit that the |
I'm slightly worried about the "view class"/"extension struct" syntax looking too much like class syntax, even though it really isn't a class. The Also, if it is really about assignability, we may want to allow non-interface types in the I think I prefer the |
I think we should avoid For |
|
I don't understand what you are saying here. In this proposal I believe there is exactly the same relation between members declared in an extension struct and the interface as there are between members declared in a class and an interface that it implements. I don't understand what relation you see the latter that is missing in the former.
I don't see an argument for doing this, and I don't propose to do this. Can you expand on why you see it as something we should do?
I don't know what you mean by a type requirement here, can you expand?
That syntax is reasonable, but to be clear it provides different affordances. In this proposal the new view type does actually implement the interface. In the view proposal, the new view type cannot implement an interface. |
Indeed, there is no subtype relationship, we only check that every member is implemented with a correct override. But when the view has an Also note that the boxed object preserves the implementation of all methods declared in the view, so |
Yes, I was being brief. In this proposal, if an extension struct
In the view proposal, if a view
My primary concerns on this front with the view proposal are as follows:
|
We could actually start with a zero-cost abstraction proposal (view / extension struct, whatever) where there is no support for We could then add boxing as an enhancement later on, yielding some extra time to think about it and implement it. Here's an example using views (with no support for view V on T {
... // Methods as needed for `V`.
}
box struct C(V that) implements /*Whatever you want*/ {
... // Manually implemented members, where you want custom behavior.
// Remaining members will be implicitly induced forwarders to `that`.
} The struct The difference is that I think this means that the boxing mechanism is made slightly more general (it could be used on any type, not just zero-cost abstractions), and we do get to specify the subtype relationships and check that they are satisfied, and we allow for some implementations to be provided by a mixin or a superclass, etc. etc. |
A boxing view is really just a wrapper with implicit forwarding. It's a class, it creates objects. We can make it as struct instead, in case we don't want to guarantee identity, and want to box/unbox as needed, but it's still something which retains its runtime type across assignments, even to So, do we want both:
They're different things. |
What I'm proposing is that we remove everything about boxing from the view / extension struct declaration, and then we introduce a The point is that (1) a user can write whatever they want in order to override the forwarding implementation, and get all the forwarding methods for free; (2) you can have multiple ways to box a view / extension struct, if you want to This makes a view / extension struct a pure zero-cost abstraction, and it provides physical wrapping as a separate mechanism (which is by the way able to do everything which was otherwise handled via the boxing part of the view proposal, and then some). |
I think my main issue here is that I don't understand the motivation for In classes
An extension struct seems to get three of those:
An extension struct does not introduce an implicit (implementable) interface:
So extension structs introduce a type (with an object signature - the set of member signatures), but not an interface (they're not implementable). That's not new, so does function types. The motivation for this is given as:
It says "If we want to preserve the former ...". Why do we want to preserve subtyping? We can allow assignability without subtyping, like we do for callable objects and function types. If we want to allow a Or we can simply say that covariant assignability is allowed inductively at any position in the type, so a I don't think I want the subtyping. A view is not an object, it's a fleeting locally-applied static wrapper. In fact, I think that I don't want the extension struct types to be reified at runtime at all. At runtime, there is only the underlying type. Views is an entirely static thing. There should be absolutely no need for the type at runtime. Whether we want assignability depends on the more precise details of the "view" feature. I think the current "views" proposal handles it well. |
I'm very much aligned with @lrhn here. When I read @leafpetersen, in particular, when you said:
I am having a hard time connecting this with the example above. If I'd go back here to the original goal: we are not looking at creating additional subtyping relationships, we are looking at a succinct way to synthesize nonvirtual forwarding stubs. I believe a different keyword, like the |
Another (possibly different) way to say the same thing: When a thing implements an interface, I expect to be able to cast it to that interface and get the implementation from that thing. That's what implementing an interface means. Like @sigmundch says, when I read Extension structs/view are not using dynamic dispatch. It's all static dispatch on the static extension struct type that the object is currently viewed at. Saying that that view implements an interface is meaningless because it does not actually provide anything when the object is used at the interface type. |
For consistency with records, I would like syntax with wavy brackets for user named fields, like data class Foo({int x, int y}); |
I've opened new issue #3198. |
The proposal for structs and extension structs here uses the declaration forms:
The idea of re-using the basic class syntax is fairly core to the proposal (though we could certainly incorporate pieces of this proposal into other proposals), but the choice of keywords is fairly arbitrary. The proposal lists a number of alternatives, largely around either choosing a new keyword (e.g.
view
, orrecord
), or around using a modified onclass
(e.g.data class
andview class
).This issue is for discussion of main declaration syntax. Discussion of other syntactic choices (e.g. the primary constructor syntax) should be done in a separate issue.
The text was updated successfully, but these errors were encountered: