Skip to content

const correctness like in C++ #1567

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

Closed
elsamuko opened this issue Apr 8, 2021 · 8 comments
Closed

const correctness like in C++ #1567

elsamuko opened this issue Apr 8, 2021 · 8 comments
Labels
enhanced-const Requests or proposals about enhanced constant expressions feature Proposed language feature that solves one or more problems

Comments

@elsamuko
Copy link

elsamuko commented Apr 8, 2021

I'd love const correctness for parameters and methods similar to C++.
If I mark a method as const, it guarantees, that calling it won't change the instance.
If I mark parameters as const, it guarantees, that calling it won't change the parameters.
In C++ this feature is a great assistance to avoid side effects and helps the compiler to optimize.

Example implementation would be:

import 'dart:io';

class C {
  int i;
  int k;

  C(this.i, this.k);

  int sum() const {
    // i and k are not changed -> sum() can be const
    return i + k;
  }
}

int sum(const int i, const int k) {
  // i and k are not changed -> i and k can be const
  return i + k;
}

void main() {
  C c = C(2, 3);
  print(c.sum());
  print(sum(2, 3));
}
@elsamuko elsamuko added the feature Proposed language feature that solves one or more problems label Apr 8, 2021
@lrhn
Copy link
Member

lrhn commented Apr 9, 2021

Knowing that calling C.sum cannot change the C instance can be convenient.

One question is whether it would be shallow or deep. Can a const function call any non-const function? Probably not, which makes it deeply immutable, but also very restrictive.

Should there be a way to circumvent the const-ness requirement (like const_cast in C++)? It's there for a reason. Sometimes a seemingly constant function wants to cache a value, and updating the cache is a non-constant operation. If so, it means that it's not really a soundness property (something the compiler can depend on), just a documentation tag to force a specific user behavior.

The const int i parameter means (I guess) that you can only invoke const methods on i and k and only pass them to other const variables. (Not a big issue for int, which is immutable, but makes sense for other classes).

It would mean that function types would need to be const annotated too. Each parameter, the return type, and the function itself, can be const. For subtyping, an X is assignable to const X (same object, promise not to modify it), so num Function(const num) const is a proper subtype of const num Function(num).

@elsamuko
Copy link
Author

elsamuko commented Apr 9, 2021

  • in C++, const is deep
  • in C++ you can use mutable to allow state changes for sth like caches or mutexes:
    https://arne-mertz.de/2017/10/mutable/
  • const for a return type can be used, if you return a const& in C++, e.g. const& std::vector<...> getList() const to avoid copying, if you need read-only access on the return type

@mraleph
Copy link
Member

mraleph commented Apr 9, 2021

Note that there is no soundness guarantee from const in C++ because it does not come with uniqueness guarantees. Even though this is const pointer there might be other pointers in the program which are not const meaning that if your const function is calling somewhere (or just uses other pointers) it might end up changing your seemingly immutable fields.

struct A {
    int x;
    A* v;

    void foo() const {
        use(this->x);
        v->x = 11;
        use(this->x);  // Is x the same? Nobody knows because |v| might be the same as |this|
    }
};

This also means that compiler usually can't really use const for much.

@ykmnkmi
Copy link

ykmnkmi commented Apr 16, 2021

possible case:

// lib

class Route {
  const Route(this.path);

  final String path;
}

class App {
  // ...

  Route route(const String path) {
    return const Route(path);
  }
}

// code

const app = App('app');

@app.route('/')
void hello() {
  // ...
}

@Levi-Lesches
Copy link

Just pointing out that this syntax can conflict with #1684

@eernstg eernstg added the enhanced-const Requests or proposals about enhanced constant expressions label Dec 1, 2021
@guneshmunjal
Copy link

@Levi-Lesches is this issue still open??

@Levi-Lesches
Copy link

@guneshmunjal, I'm not part of the Dart team nor the original author, but yes, it appears to still be open, but I don't know how high of a priority it is at the moment.

@munificent
Copy link
Member

I like const correctness in C++. This isn't an unreasonable request for Dart, or a bad idea. But, realistically, this would be a huge language and core library change and I think it's exceedingly unlikely that it would be feasible or a good fit for Dart.

I'm going to close this out because I can't see us realistically taking this on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhanced-const Requests or proposals about enhanced constant expressions feature Proposed language feature that solves one or more problems
Projects
None yet
Development

No branches or pull requests

8 participants