Saturday, December 29, 2012

I Did Not Understand Constant Constructors

‹prev | My Chain | next›

If you really want to understand Dart constant constructors, read the comments to last night's post on the subject. Lasse wrote an excellent, succinct introduction to the subject. As for me, I learn best by playing with code, so tonight I follow up on yesterday's attempt at understanding.

The main thing that I was doing wrong yesterday was in instantiating my constant objects. I had been using the usual new keyword:
class PerfectCookie {
  final number_of_chips;
  const PerfectCookie({this.number_of_chips});
}

main() {
  var perfect_cookie = new PerfectCookie(number_of_chips: 42);
}
It turns out that const is overloaded to not only declare constant values, but it can also instantiate constant objects:
main() {
  var perfect_cookie = const PerfectCookie(number_of_chips: 42);
}
Following through with Lasse's notes, I expect that multiple instances of constant objects are the same thing—that is they should be identical:
main() {
  var pc1 = const PerfectCookie(number_of_chips: 42),
      pc2 = const PerfectCookie(number_of_chips: 42);

  print("pc1 and pc2 identical? ${identical(pc1, pc2)}");
}
Running this code results in:
pc1 and pc2 identical? true
As pointed out to me, constant constructors create compile-time constants. Another way of saying this, and this is what I missed yesterday, is that all of the associated values are known (and fixed) at compile time.

At the risk of repeating Lasse's entire comment, Dart used to allow only these compile time constants to be assigned to instance variables at compile-time. I never really understood what those compile-time constants were back then and, now that instance variables are lazily evaluated, they don't matter as much. Ah well, that's progress.

I still find it strange that using the regular new keyword works for constant constructors:
class PerfectCookie {
  final number_of_chips;
  const PerfectCookie({this.number_of_chips});
}

main() {
  var pc1 = const PerfectCookie(number_of_chips: 42),
      pc2 = const PerfectCookie(number_of_chips: 42),
      pc3 = new PerfectCookie(number_of_chips: 42);

  print("pc1 and pc2 identical? ${identical(pc1, pc2)}");
  print("pc1 and pc3 identical? ${identical(pc1, pc3)}");
}
The first and second "perfect cookies" are identical because their values are set at compile-time. The third perfect cookie is not evaluated until runtime. Even though the value for the number of chips is the same for all three objects, the Dart compiler cannot guarantee that the number of chips is fixed, hence the third instance refers to a different object than the first two:
pc1 and pc2 identical? true
pc1 and pc3 identical? false
I can seen the suggested benefits of using constant constructors as enums and sentinels. I may have to explore annotations because I was not even aware of this feature of Dart.

New to me is that Dart's case statement requires compile-time constants. So I might write the following:
main() {
  var pc1 = const PerfectCookie(number_of_chips: 42),
      pc2 = const PerfectCookie(number_of_chips: 42),
      pc3 = new PerfectCookie(number_of_chips: 42);

  print("pc1 and pc2 identical? ${identical(pc1, pc2)}");
  print("pc1 and pc3 identical? ${identical(pc1, pc3)}");

  const pc42 = const PerfectCookie(number_of_chips: 42),
      pc84 = const PerfectCookie(number_of_chips: 84),
      pc99 = const PerfectCookie(number_of_chips: 99);

  var cookie = pc1;
  switch(cookie) {
  case(pc42):
    print(42);
    break;
  case(pc84):
    print(84);
    break;
  case(pc99):
    print(99);
    break;
  }
}
Which would result in printing the value of 42 since the pc1 and pc42 are the same:
pc1 and pc2 identical? true
pc1 and pc3 identical? false
42
Constant constructors still seem of limited use in typical Dart coding, but I feel much better for having (mostly) explored this corner of the language.


Day #614

6 comments:

  1. Cabanacatalogs a unit of Cabana Obonu Outdoors LLC is proud to say that our products are authenticated with the best fabric made true to size to fit our customers’ specific needs.

    online shopping
    online shopping for men
    online shopping for women

    ReplyDelete
  2. Norton also scans files using emulation technology. This process happens in a fraction of a second. It utilizes various optimization tools to enhance the user experience. So, what are you waiting for? Let's get started with Norton by accessing
    https://sites.google.com/a/sy4norton.com/setup
    https://sites.google.com/a/sy4norton.com/setupnortonnu16
    https://sites.google.com/a/sy4norton.com/setupmynorton
    https://sites.google.com/a/sy4norton.com/downloadnortonsetup

    ReplyDelete
  3. Hey! I was just exploring and came across your site. The articles and blogs were quite interesting to read. I am from technological field. If someone is interested to read about Antivirus software, then do visit my site
    mcafee.com/activate or
    bitdefender login
    norton.com/setup office.com/setup

    ReplyDelete
  4. Hey here is the Bodden I like your post and such a nice information's do when you need any software buy so you can go and read about this and buy Webroot and many others also here is the know about some extender.linksys.com internet security.

    Webroot Login

    ReplyDelete
  5. Allied Paralegal Services is a licensed paralegal with the Law Society of Ontario, offering a wide range of legal assistance to our clients. Backed by years of experience and exhaustive knowledge, we provide the favorable results you come looking for.
    Paralegal Near Me
    Paralegal Services Ontario
    Paralegal Services Toronto
    Paralegal Services Near me
    paralegal services near me
    justice of the peace Ontario
    lawyers near me

    ReplyDelete
  6. High quality Indica marijuana weed is found near Afghanistan, Pakistan, India, and Turkey. It is cultivated for many purposes; some of them are seeds and leaves.https://smokyexpress.ca
    Hybrid Cannabis
    Indica marijuana weed
    Shatter Extracts
    Magic Mushrooms
    Sativa marijuana weed

    ReplyDelete