Skip to content
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

Add data classes #314

Open
ranquild opened this issue Oct 31, 2017 · 25 comments
Labels

Comments

@ranquild
Copy link

@ranquild ranquild commented Oct 31, 2017

Immutable data are used heavily for web applications today, commonly with Elm-like (redux, ngrx, ...) architectures. Most common thing web developer is doing with data is creating a copy of it with some fields changed, usually propagated to the root of state tree. JavaScript has spread operator for this. There should be a easy way to use immutable data structures in Dart. I would like to have data classes (inspired by Kotlin) in Dart. Possible API:

data class User {
  String name;
  int age;
}

Compiler assumes that all fields of data class are immutable. Compiler adds equals implementation based on shallow equals, hashCode implementation based on mix of all object fields, toString implementation of the form <Type> <fieldN>=<valueN>, and copy function to recreate object with some fields changed.

You may argue that there is already Built value package that allows to do similar things, but we have many issues with package, mainly:

  1. It requires writing a lot of boilerplate code
  2. It requires running watcher/manual code generation during development.
  3. It requires saving generated files to repository because code generation time is too large for big applications.

I have found that using built value actually decreases my productivity and I do my work faster with even manually writing builders for classes.

If data classes would be implemented on language level, it would increase developer productivity and optimizations can be made when compiling code to particular platform.

@eernstg

This comment has been minimized.

Copy link
Member

@eernstg eernstg commented Oct 31, 2017

No promises, but it's on the radar..

@freewind

This comment has been minimized.

Copy link

@freewind freewind commented Apr 6, 2018

Or inline make it shorter?

data class User(String name, int age)
@dcovar

This comment has been minimized.

Copy link

@dcovar dcovar commented Apr 7, 2018

Are there any updates on this enhancement? I'm currently working with Flutter, and having come from the Kotlin/Android world, this is something that would make the transition a lot nicer. Especially when creating ViewModels, or even simple data models, this would make it a lot easier.

@zoechi

This comment has been minimized.

Copy link

@zoechi zoechi commented Apr 8, 2018

@dcovar don't expect anything short term. It won't be part of Dart 2.
They might tackle it after Dart 2.
The built_value package works well enough for me.

@fmatosqg

This comment has been minimized.

Copy link

@fmatosqg fmatosqg commented Apr 29, 2018

Community could write a package similar to Lombok who autogenerates code from a valid annotated source code file.

https://projectlombok.org/

One more thing for the wishlist on either flutter/flutter#13607 or flutter/flutter#13834, not sure which

@zoechi

This comment has been minimized.

@Cat-sushi

This comment has been minimized.

Copy link

@Cat-sushi Cat-sushi commented Oct 8, 2018

User should have implicit constructor const User({this.name, this.age});, correct?

@saolof

This comment has been minimized.

Copy link

@saolof saolof commented Dec 25, 2018

One thing worth mentioning is that data classes and sealed classes can both be viewed as an instance of a metaclass. If enough different kinds of special-cased classes are proposed, at some point it might become better to add metaclass programming to the language, with a few individual cases of syntax sugar.

Dart already kind of flirts with the idea when you look at what was needed to make the mirrors API work.

@andrewackerman

This comment has been minimized.

Copy link

@andrewackerman andrewackerman commented Apr 11, 2019

I support this, but suggest also adding toJson and fromJson methods to the generated code so data class instances can be easily (de)serializable.

@i-schuetz

This comment has been minimized.

Copy link

@i-schuetz i-schuetz commented Apr 12, 2019

@andrewackerman Data classes shouldn't have more than a generic minimum to be used as domain entities, this being equals/hashCode, copy and toString. Serialization isn't a universal requirement and even less to an industry standard (which not necessarily everyone wants to use / can become outdated) like JSON.

@eernstg

This comment has been minimized.

Copy link
Member

@eernstg eernstg commented Apr 12, 2019

For current activities in this direction, you may want to consider also issues like the following: #117, #125, #225, #308.

@andrewackerman

This comment has been minimized.

Copy link

@andrewackerman andrewackerman commented Apr 12, 2019

@i-schuetz Then maybe there can be some optional attributes that can be added to the class declaration so these features can be added for people who need them? Serialization may not be a universal requirement but I'd bet that it would be needed often enough that people would want to at least have the option. Otherwise it would largely defeat the purpose of having a concise data class declaration syntax but then have to manually create the (de)serialization methods.

And it's not like it would need to serialize to actual JSON strings. It could serialize to Map<String, dynamic>, which is itself easily convertible to and from JSON.

@i-schuetz

This comment has been minimized.

Copy link

@i-schuetz i-schuetz commented Apr 12, 2019

Maybe something generic along the lines of Swift's Codable could make sense, but this is an entirely different feature. Although equals and toString are convenience as well - I remember for example in Haskell this being solved via type classes (which to be implemented require only to write a word practically). I don't know which exact considerations Jetbrains did to shape data classes the way they did in Kotlin. It's probably something along the lines that equals and toString make sense always. Serialization, as you say, it's used only "often".

@dcov

This comment has been minimized.

Copy link

@dcov dcov commented Apr 12, 2019

I agree with @i-schuetz that adding a Codable protocol is probably the best option. It could even make its way into Flutter plugins (and the framework itself), where the data you pass to the 'other side' has to be encoded first.

@kevmoo

This comment has been minimized.

Copy link
Member

@kevmoo kevmoo commented Apr 12, 2019

@leafpetersen @munificent @lrhn – should be moved to the language repo?

@leafpetersen

This comment has been minimized.

Copy link
Member

@leafpetersen leafpetersen commented Apr 12, 2019

@leafpetersen @munificent @lrhn – should be moved to the language repo?

yes, thanks.

@kevmoo kevmoo transferred this issue from dart-lang/sdk Apr 12, 2019
@FullstackJack

This comment has been minimized.

Copy link

@FullstackJack FullstackJack commented May 8, 2019

Let's kill the argument that moving to Dart (Flutter) from Kotlin is like moving back in time several years.
https://medium.com/@wasyl/kotlin-developers-thoughts-on-dart-1f60c4ad21ad

@swavkulinski

This comment has been minimized.

Copy link

@swavkulinski swavkulinski commented May 15, 2019

The point of having data classes (apart from immutability) is to have implicit methods e.g. toString(), hash(), == for free.

More importantly for immutable class there is a need for mutation method (e.g. Kotlin apply() aka copyWith() in other languages) with default implementation to avoid boilerplate of mutation method.

@benoit-ponsero

This comment has been minimized.

Copy link

@benoit-ponsero benoit-ponsero commented May 23, 2019

Hello,
I'm looking for dart, the typesystem is great, it's well thought but i think there is a lack of functionnal support.
I'm a scala developer and we have "case class" for this.
It's provide toString, equals, hashCode and a copy method with optional params.

This proposal is great and could attract more developer like me. Do you know when it could be implemented ?

@jodinathan

This comment has been minimized.

Copy link

@jodinathan jodinathan commented May 23, 2019

@benoit-ponsero is the method copy done by reflection?

@benoit-ponsero

This comment has been minimized.

Copy link

@benoit-ponsero benoit-ponsero commented May 23, 2019

It's a compiler generated method.

@jodinathan

This comment has been minimized.

Copy link

@jodinathan jodinathan commented May 23, 2019

Then it must be tree-shaken when built with dart2js.

@agusbena

This comment has been minimized.

Copy link

@agusbena agusbena commented Jun 6, 2019

Here in our company we are crossing our fingers to get this feature arrive son!
Please!

@JSANL

This comment has been minimized.

Copy link

@JSANL JSANL commented Aug 6, 2019

I'm also hoping that this will be added, a way to have a default implementation of ==, hashCode and toString would make many things much easier and faster.

@marcelgarus

This comment has been minimized.

Copy link
Contributor

@marcelgarus marcelgarus commented Sep 5, 2019

For a more lightweight alternative to built_value, which will be syntactically closer to possible language-level data classes, I implemented a package data_classes.
Basically, you write a mutable class (like MutableUser) and it generates the immutable pendant (User) with a constructor, converters to and from the mutable class, custom ==, hashCode and toString() implementations, and a copyWith method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.