-
Notifications
You must be signed in to change notification settings - Fork 205
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
Structs and extension structs as a solution for data classes and wrapper-less views #2360
Comments
My simple question is why are those two separate feature sets discussed in the same issue/ proposal? |
I (and others) have concerns about the growing surface area of the language. Each additional feature we add is a source of cognitive load on the user. One of my goals in this proposal was to try to reduce this cognitive load, by making the new features largely be restrictions on existing features. So the idea would be that structs are restrictions on classes, and extension structs are restrictions on structs. This is essential, and I think I've somewhat convinced myself that it would be better to build both of them separately off of classes (e.g. |
I hope this is the right place to post this. I've been thinking about the proposal and the discussion to generalize primary constructors to be allowed in classes too (#2364). I strongly want the latter. I think it would honestly provide more value to more users than anything else in the struct proposal. And I think it's entirely doable. Here's a strawman then of a couple of other features we could compose that I think might cover the various use cases:
Here's how those compose for the various use cases:
This is pretty close to the existing view and struct proposals, but I'm trying to tease out primary constructors, |
@munificent From some of the discussion in other issues, I think it is expected that structs do not allow for polymorphism. But here, it says that polymorphism is the default behavior and you have to (very explicitly) opt out. What I'd like to understand is why a polymorphic value type is needed, as it would always need to be boxed (therefore having reference semantics). The only case of limited struct polymorphism I can think of is a Rust-style tagged union, but this would be accomplished by pub enum Shape {
Rect { lt: Point, rb: Point },
Circle { center: Point, radius: f64 },
// ...
} switch struct Shape;
struct Rect(Point lt, Point rb) extends Shape;
struct Circle(Point center, double radius) extends Shape; My current understanding of type modifiers is that it matches Dart's "open by default" model by making restrictions opt-in. For structs I think the opposite should be true: restrictive by default, opt into openness. I would not expect |
You might want a value type representing a vector to implement I don't think boxing is a huge problem. Yes, you might need to box the value type when it ends up in a collection or in a variable whose static type is some interface. That's OK. I think the important part is that when you unbox it later, you're allowed to get a value back that does not guarantee that it will be But I'm also not an expert on the use cases some users have around extremely lightweight value types in Dart, so there may be a subtlety I'm missing. |
@munificent I think this is why I misinterpreted the "Inline allocation" portion. I don't think the ability to have a contiguous array of a struct is related to polymorphism and vtables as outlined in your first comment. It's instead related to variance. The difference between a This reminds me of the various issues with getting value types into Java. Lots of really good info here: https://openjdk.org/projects/valhalla/ (current) and https://openjdk.org/projects/valhalla/legacy (for older prototypes and designs) As for extending structs, extending would completely prevent unboxing EXCEPT in the case where you have a sealed struct.
For Flutter there are many struct-ish types like For other lightweight value types, there are FWIW, you can somewhat emulate unboxed value types on the VM today with some very careful code. While mostly performant it isn't fun to write. |
@munificent, I think it would be very beneficial for users to receive these as separate features as you describe. Specifically, primary constructors and structs cover various use-cases where classes are fine but boilerplate-y and can use optimization.
While a struct isn't the same as a class, it seems more like a subset of a regular class (at least intuitively). Would it make sense to make
Small detail, but I think this will probably help |
Any update on this? Is the proposal discarded? |
The feature specification about inline classes contains many elements from this proposal, covering the semantic space which was described as 'views' in this issue. Records support the notion of being a value, in the sense that records are immutable and their equality is based on pairwise getter equality ( So there are many elements from here which are already covered in other language features. One missing part is a concise syntax for data classes. The main issue for that is #314, and other issues can be found by looking for the label data-classes . |
I'm looking forward to seeing this at the CHANGELOG.md. |
This is a meta-issue to collect up discussion around a proposal I've landed here. This issue is intended to capture broad discussion about the approach. Specific points of discussion around the proposal should be filed as separate discussion issues: I will link the major discussion points in here as appropriate.
Summary
The core of this proposal is to explore an approach to supporting data classes and wrapper-less views while hewing as closely as possible to the syntax and semantics of existing Dart constructs. A secondary goal is to support object representations that are more amenable to compiler optimization, having predictable space layout, loosely specified identity, and limited polymorphism.
The approach here has the user-facing goal that for a consumer of APIs, the basic affordances of a declaration should be obvious to anyone familiar with classes (i.e. what assignments are allowed, and what methods are available). Quoting from the introduction of the proposal:
Note that while this proposal covers two separate feature sets, they are not necessarily tied together. We could choose to ship one without ever shipping the other, or we could choose to split them into unrelated features. Even if we ship both as designed here, we could (and likely would) choose to ship the pieces separately given existing timelines and plans.
Discussion issues
The text was updated successfully, but these errors were encountered: