-
Notifications
You must be signed in to change notification settings - Fork 209
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
Allow records to implement interfaces #3071
Comments
Records are like very simple classes that already exist. You cannot make them implement new interfaces. A Dart typedef doesn't create a new type, and it cannot add interfaces to existing types (that requires a new type). Essentially, it does not make sense to add interfaces to records, Dart records are simply not something you can add interfaces to, not any more than you can add interfaces to function types. |
@lrhn is right. While it might be tempting to use a typedef on a record type as a lightweight way to define a new type, that's going against the grain of the language. A typedef is just an alias for an existing type. It doesn't create a new type with its own properties and capabilities. If you want that, a class declaration is what you want. |
Understandable, but to be fair, coming from any other language that implements a "record" type (F#, C#, Java), this is pretty non-intuitive IMO. I am okay with the fact that this is not possible, but this is definitely not in line with the ethos of Dart being familiar to those coming from other languages. E.G. public interface IData<T>
{
T Data { get; }
}
public record PersonWithData<T> : Person, IData<T>
{
public T Data { get; init; }
} public record EnhancedList<T>(List<T> inner) implements
ForwardingList<T>,
Mappable<T>,
Filterable<T, EnhancedList<T>>,
Groupable<T> {}
interface ForwardingList<T> extends List<T>, Forwarding<List<T>> {
List<T> inner();
//…
} I'd also add, that is doesn't make much sense (to me at least) that records can't be used in sealed class hierarchies. I guess records are meant to be more of a tuple type than a data class? I guess that would make sense if dart had actual primitive types, but the limitations placed on records (as of now) seem to be counter productive and pretty limiting. Was hoping to not have to keep using Freezed, or Equatable, etc, but the goal of records seems to be aimed at solving a different set of problems (or at least only a subset). Anyhow, thanks for adding them. |
Not just "more of". Records are precisely tuples, nothing more, nothing less. The only fancy part is that some of the positions can be named with an identifier instead of an integer. It's still just a product type. And there are structural types, meaning that they do not have a name, they are defined entirely by their structure, which is why they cannot implement interfaces or be part of class hierarchies. Dart records are not intended to be data classes. That's why they're not very good at it. They're low-level building blocks, which makes it easier to, say, return more than one value. They're closer to an abstraction over an argument list, than to a class instance. The C# records are immutable classes or structs with automatic field based equality. A |
But C# record structs have with expressions, can use annotations, implement interfaces, etc. So I guess the only confusion (on my part) is the naming of Dart records creates the expectation that a record would be something more akin to what one is used to when coming from any other language that provides a similar construct.
What's the reasoning behind not just calling them tuples then? I mean, outside of the Database world - the two aren't really interchangeable (in terms of naming at least) that I am aware of, and when taking into account the features that a record abstraction has in pretty much every language prior to Dart , it seems like an odd naming decision. Anyhow, I am guessing that the plan is to leave actual data classes as an issue to be solved by libraries? Or something to be tackled when the static meta programming feature is complete? |
"Record" in C# and Java is really more like "data class" in Kotlin. It's a separate feature (with a confusingly chosen name). We're interested in exploring those capabilities for Dart too, but it's different from records. See this PR for one piece of this. |
Tuples suggests only integer positions, the "record" name is supposed to suggest that you can also use named positions. It's an existing word already used to describe name-indexed product types. The distinction between records-where-all-keys-are-consecutive-small-integers and tuples, or records and tuples-where-fields-can-be-accessed-by-name is mostly perception. The underlying structure is a product type, the names of projection functions is just syntactic sugar. (But not entirely, since it allows |
I have been trying out the new records feature, and while they are a definite upgrade to the language, they seem somewhat non intuitive to use for someone coming from programming mostly in F# and Typescript.
Consider the following code,
consider there is a library full functions that return different result types similar to the SMAResult, lets say I want to accept anything with the shape
as opposed the the Quote type in the simpleMovingAverage function, which would allow calculation of results from other functions that do similar calculations.
In situations like this, where it's much simpler to use records as opposed to classes, mainly due to the structural equality aspects of the type being implemented for you, it would be nice for records to be able to implement interfaces.
Coming from F# this is kind of second nature
converted to dart I am guessing that would be something similar to
in typescript this is all much easier because the entire type system is structural so every
type is an interface itself, which makes thing a lot simpler, no interfaces to define etc.
Currently, not being able to use records in these types of contexts seems somewhat limiting IMO, if I only need a bag of values and no methods, but I need to ensure every type has some subset of fields, it's not currently possible (that I am aware of ) in the current implementation of records.
Another option (that does't seem feasible) is so called "Statically Resolved Type Parameters" which are simply member constraints, and allow a form of duck typing.
Maybe there is a way to accomplish the same effect that I am unaware of? If not, I would consider this to be a nice feature to have and allow better overall use of records.
The text was updated successfully, but these errors were encountered: