3

I know that const is compile-time constant in dart, but I don't understand mechanism behind const [F0, F1, F2] in the following code:

class Foo {
  static const F0 = 'F0';
  static const F1 = 'F1';
  static const F2 = 'F2';
  // const list of const values I guess...
  static const CONST_LIST = const [F0, F1, F2]; // please explain this line
  static final String FOO = CONST_LIST[0]; // ok
  // compile error: 'const' varaibles must be constant value
  // static const String BAR = CONST_LIST[1];
}

main() {
  // is CONST_LIST const or not?
  // below line it's ok for dartanalyzer but
  // in runtime: Cannot change the content of an unmodifiable List
  Foo.CONST_LIST[1] = 'new value';
}

I noticed that const is required by dart analyzer in const [F0, F1, F2]; but it does make list more like final (runtime immutable list) rather than compile time const.

UPDATE:

Another question is why CONST_LIST[1] is not "constant value". See commented declaration of Foo.BAR.

Michał Šrajer
  • 30,364
  • 7
  • 62
  • 85
  • Const object must have deep immutability. So if you have const variable it should refer const object that consists from const objects. – JAre Nov 16 '14 at 15:09
  • What makes you think that this makes it more like a final? The problem with the `static const String BAR = CONST_LIST[1]` is that the array accessor is currently not supported in a constant expression (see http://dartbug.com/18389). Seems a bug in Dart analyzer. – Günter Zöchbauer Nov 16 '14 at 15:23
  • @JAre: what is mutable in CONST_LIST? it's declared const, const list with all values being const. How can it be more const? ;-) – Michał Šrajer Nov 16 '14 at 16:46
  • @GünterZöchbauer analyzer not being able to detect issue when assigning 'new value'. The bug you pointed out makes it more clear. Thanks. – Michał Šrajer Nov 16 '14 at 16:48

2 Answers2

4

Günter has answered the second part of your question. Here is some more information about const.

Const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.

More information in this article. Also see the following question.

Regarding the second part of your question, consider the following:

const int foo = 10 * 10;

The expression "10 * 10" can be evaluated at compile time, so it is a "constant expression". The types of things you can do in a constant expression need to be quite limited (otherwise you could run arbitrary Dart code in the compiler!). But some of these limitations are being relaxed as dart matures, as you can see in the bug which Günter linked to.

In contrast, consider the following:

final int bar = 10;
final int foo = bar * bar;

Since "bar * bar" is not a constant expression it is evaluated at runtime.

Community
  • 1
  • 1
Greg Lowe
  • 15,430
  • 2
  • 30
  • 33
  • so dart compiler is not (yet?) smart enough to figure out value of `CONST_LIST[1]` because of complexity of `[]` operator? – Michał Šrajer Nov 16 '14 at 23:14
  • Yup - probably because in Dart you can override the [] operator, so this is basically the same as calling a method. – Greg Lowe Nov 16 '14 at 23:22
  • 1
    Pedantically: The `10 * 10` expression *is* a compile-time constant expression and will be computed at compile time. If you then write `final int bar = foo * foo;`, then *that* expression isn't constant, because `foo` is a non-const variable. If `foo` was const, then `foo * foo` would also be constant. – lrn Nov 17 '14 at 16:58
  • Cool thanks. I've updated the comment. I hope I pass the pedantic test now ;) – Greg Lowe Nov 17 '14 at 21:13
2

There is an open bug for this: see https://github.com/dart-lang/sdk/issues/3059

cambunctious
  • 8,391
  • 5
  • 34
  • 53
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567