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

Value types (deep immutability) #501

Open
DartBot opened this issue Nov 17, 2011 · 12 comments
Open

Value types (deep immutability) #501

DartBot opened this issue Nov 17, 2011 · 12 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). core-m type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented Nov 17, 2011

This issue was originally filed by [email protected]


I would like to suggest the addition of 'readonly' as a keyword to complement 'final'. It's use should instruct the compiler to enforce the deep immutability of the variable it describes. This is useful to people using an API, and provides strong hints for optimization possibilities for the compiler and VM.

For example, this is legal:

  Bar mybar;
  foo(mybar);

  void foo(final Bar bar) {
    bar.thing = other_thing;
  }

I suggest that:

  Bar mybar;
  foo(mybar);

  void foo(readonly Bar bar) {
    bar.thing = other_thing;
  }

should be illegal and should error during compilation when assignment to bar.thing is attempted.

Similarly, any attempt to take a non-readonly reference to a readonly variable should be illegal.

This may require methods on an object to be marked as readonly to indicate that they don't mutate |this|, though it may be possible to statically determine this.

@gbracha
Copy link
Contributor

gbracha commented Nov 17, 2011

Deep immutability is a very useful concept. Unlike shallow immutability (final) it isn't a property of a variable however - it is a property of an object. It just won't be useful if another reference to that object can make changes to it.

Deep immutability is a complex issue. It would be nice to have, but it will take some time to see if we can come up with a workable solution.


Set owner to @gbracha.
Removed Type-Defect label.
Added Type-Enhancement, Area-Language, Accepted labels.

@gbracha
Copy link
Contributor

gbracha commented Nov 17, 2011

Changed the title to: "Value types (deep immutability)".

@DartBot
Copy link
Author

DartBot commented Nov 18, 2011

This comment was originally written by [email protected]


Just to clarify or emphasize what's already stated above, immutability and readonly are different concepts. (You might have a readonly view of an object that can be mutated by something else.)

Also, related, we currently have interface FrozenElementList used by some DOM APIs.

@DartBot
Copy link
Author

DartBot commented Nov 18, 2011

This comment was originally written by [email protected]


Thank you for clarifying. My original intent was for readonly as a property of a var. Ie, you can create a readonly reference for the scope of a method, or you could define a class member as readonly which would require it to be set at construction.

Creating a non-readonly reference to a reference that has been marked readonly would be a compile time error (as I believe it can be statically determined). Similarly, calling non-readonly methods on a readonly reference would be an error, though I'm not sure if that can be determined statically without some annotation from the developer on the method.

@DartBot
Copy link
Author

DartBot commented Nov 18, 2011

This comment was originally written by @yjbanov


I think it is worth a consideration, although I'd recommend the more familiar keyword "const" rather than "readonly", since one of the major goals is to keep the language as familiar as possible to programmers of existing languages, in this case C#/C++.

A related topic is read-only API for certain core Dart classes. I posted a proposal (includes a working prototype) for a read-only API for some of Dart's core collections:

http://goo.gl/R30KV

Which grew out of this long discussion:

http://goo.gl/4Jo0a

Yegor

@anders-sandholm
Copy link
Contributor

Added this to the Later milestone.

@DartBot
Copy link
Author

DartBot commented Aug 29, 2012

This comment was originally written by @polux


I would be so glad to see this happening. Here are some thoughts:

  - Dart could provide deep immutability by construction (you can only construct a deeply immutable value from deeply immutable values), and this could be enforced at runtime, even in unchecked mode. The downside of this approach is that it requires a very functional style and makes the building of graphs almost impossible (unless you comme up with some notion of lazy values, I guess).

  - Alternatively, we could have a "freeze" operator which would mean "from now on, this value is deeply immutable". Then checked mode would check that none of its recursively subvalues is ever modified. I guess that would be very costly but on the other hand it would offer an unprecedented flexibility.

  - A variation around the alternative is to freeze by copy, which would make the subsequent checks much easier, but would induce possibly unbearable runtime costs.

@kasperl
Copy link

kasperl commented Jul 10, 2014

Removed this from the Later milestone.
Added Oldschool-Milestone-Later label.

@kasperl
Copy link

kasperl commented Aug 4, 2014

Removed Oldschool-Milestone-Later label.

@DartBot DartBot added Type-Enhancement area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Aug 4, 2014
@davidmorgan
Copy link
Contributor

FYI https://github.com/google/built_value.dart is a library that uses codegen to support value types. If you use it for all your types, you have deep immutability.

@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug and removed accepted type-enhancement A request for a change that isn't a bug labels Feb 29, 2016
@lrhn lrhn added core-m and removed P2 A bug or feature request we're likely to work on labels Dec 6, 2018
@stephenbunch
Copy link

Reviving an old thread. We use built_value, but we also like free-handing objects. With NNBD, I'm planning to roll out some best practices to our team for free-handed immutables:

class Foo {
  final int bar;

  Foo(this.bar) {
    // hashObjects([bla, bla]) from quiver library
    hashCode = bar.hashCode;
  }

  /// The `late` keyword is coming with NNBD.
  @override
  late final int hashCode;

  @override
  bool operator ==(dynamic other) =>
      // Short-circuit identical objects. BTW, BuiltValue does this already.
      identical(other, this) ||
      (other is Foo &&
      // Short-circuit unequal objects.
      other.hashCode == hashCode &&
      // Proceed to check each value individually.
      other.bar == bar);
}

I wonder if it's possible to create a language syntax that does the same thing?

immutable class Foo {
  final int bar;

  Foo(this.bar);
}

@davidmorgan
Copy link
Contributor

FWIW, and as the author of built_value I'm almost certainly biased ;) I don't think NNBD is enough to make hand-maintaining immutable value types a good idea. I wrote an article about all the problems with hand maintained immutable value types ;)
https://medium.com/@davidmorgan_14314/the-mutability-tax-6403d84f21c0

copybara-service bot pushed a commit that referenced this issue Oct 11, 2022
…ptor, webdev

collection (https://github.com/dart-lang/collection/compare/414ffa1..ca45fc4):
  ca45fc4  2022-10-07  Devon Carew  update CI config; prep for publishing (#251)

glob (https://github.com/dart-lang/glob/compare/1d51fcc..ee81279):
  ee81279  2022-10-10  Moritz  Merge pull request #62 from dart-lang/bump_deps
  b6747a1  2022-10-10  moritz  Add changelog entry
  d069e13  2022-10-10  moritz  Bump depencies

intl (https://github.com/dart-lang/intl/compare/7639a15..dda8ade):
  dda8ade  2022-10-10  Moritz  GitHub Sync (#501)

markdown (https://github.com/dart-lang/markdown/compare/f387340..d72ae07):
  d72ae07  2022-10-07  Sam Rawlins  Use fewer empty lists; non-growable (#463)

stack_trace (https://github.com/dart-lang/stack_trace/compare/17f09c2..2194227):
  2194227  2022-10-10  Kevin Moore  A bunch of cleanup, prepare for v1.11.0 (#118)

test_descriptor (https://github.com/dart-lang/test_descriptor/compare/f392f85..66f14ce):
  66f14ce  2022-10-07  Devon Carew  update the CI configuration; prep for publishing (#44)

webdev (https://github.com/dart-lang/webdev/compare/7416956..69aac60):
  69aac60  2022-10-07  Parker Lougheed  Update min SDK restraint mentioned to match pubspec (#1755)
  b175072  2022-10-07  Elliott Brooks (she/her)  Start migration of WebDev to null-safety (#1756)

Change-Id: I452b89a44cfcb7b0d9f36eeb1539ea362b29b6b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/263521
Commit-Queue: Nate Bosch <[email protected]>
Auto-Submit: Devon Carew <[email protected]>
Reviewed-by: Nate Bosch <[email protected]>
copybara-service bot pushed a commit that referenced this issue Feb 8, 2023
dartdoc:
494a6bed  2023-02-02  Sam Rawlins  Bump markdown dep to a pre-release of 7.0.0 (#3321)
ad6f1612  2023-02-02  Devon Carew  introduce an environmentProvider abstraction (#3324)
d0b73000  2023-02-02  Sam Rawlins  Prepare testing code for some upcoming Warnings (#3322)
936a7888  2023-02-01  Sam Rawlins  Add text about front-end manual testing (#3286)
cbee812d  2023-02-01  Sam Rawlins  Avoid renaming generator params (#3316)
bcaa0349  2023-02-01  Sam Rawlins  Privatize Library.sdkLib and move getClassByName (#3317)
af32def5  2023-01-31  dependabot[bot]  Bump github/codeql-action from 2.1.39 to 2.2.1 (#3313)
528e97da  2023-01-31  dependabot[bot]  Bump actions/cache from 3.2.3 to 3.2.4 (#3312)
54020672  2023-02-01  Parker Lougheed  Begin changelog for next release after 6.1.5 (#3315)

markdown:
f51c24c  2023-02-01  Zhiguang Chen  Prepend a line ending if the p tag is removed and there is an element before it in a *tight* list (#513)
dd3e3a1  2023-01-31  dependabot[bot]  Bump dart-lang/setup-dart from 1.3 to 1.4 (#510)
5f25fc9  2023-01-31  dependabot[bot]  Bump actions/checkout from 3.2.0 to 3.3.0 (#511)
54266b2  2023-01-31  Kevin Moore  Prepare to release v7.0.0 (#509)
d6ceff9  2023-01-31  Zhiguang Chen  Add line endings before HTML blocks (#508)
ccd3c8b  2023-01-29  Zhiguang Chen  Rewrite link reference definitions (#506)
e8f84dc  2023-01-24  Kevin Moore  Update GFM to 0.29.0.gfm.7 (#507)
93f67b0  2023-01-20  Zhiguang Chen  Add an `enableTagfilter` option to `HtmlRenderer` to eanble GFM `tagfilter` extension (#447)
d110770  2023-01-13  Zhiguang Chen  Rewrite SetextHeaderSyntax (#500)
c1b9bc6  2023-01-09  Sam Rawlins  Migrate from no-implicit-casts to strict-casts (#504)
3e78c08  2023-01-01  dependabot[bot]  Bump actions/checkout from 3.0.2 to 3.2.0 (#501)
417747f  2022-12-15  Zhiguang Chen  Refactor list syntax (#499)
30ec05f  2022-11-29  Zhiguang Chen  Do not escape single quote(apostrophe) inside code (#498)
c3d1136  2022-11-29  Zhiguang Chen  introduce a Line class (#494)
Change-Id: I9d971b927b72500ab84cce461a60fe1a86818e2e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/281543
Reviewed-by: Samuel Rawlins <[email protected]>
Commit-Queue: Devon Carew <[email protected]>
@pq pq mentioned this issue Nov 18, 2024
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). core-m type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

8 participants