Developer insight: Why does Dart have two constant variable variants?

What's the difference between const and final in dart?
TL;DR: const is set at coding-time and pre-compiled; final is assigned at runtime but only once.

For a while now, I've been coding a little in Dart by writing a Flutter mobile app. It's a very fun and easy to follow React-ish, SwiftUI-ish kind of language in which you can easily create beautifully looking applications with minimal effort by describing the UI a self-enclosing objects and functions. So far so good.

After leaving my tutorial Candyland and starting to write real code I hit a couple of walls and had to come back to re-read what I've just learnt. Coming from a JavaScript / Node.js environment background I was struck by the amount of types, data types, function types, return types... ugh, why can't everything just be a var like in my hippy language?! Well.. it kind of can... but not really... Dart is... well, special. It also has a const, a final and a static which are kind of similar but... no, they are really completely different and they confuse me and everybody in my current office. For clarification I'm going to add that since it's the beginning of 2021 that makes it literally just me in the home office , because we're at a Level 5 lockdown and I'm stuck at home and the only person to talk to about code return types is Mr Rubber Ducky.

In case you are unfamiliar with the concept of Rubber Ducky Debugging, let me introduce you.

That's 'Mr' Rubber Ducky to you. He's a developer's best friend.

Enough babbling, let's go one by one for my own benefit to get to know the types. What I want to know is: What is the difference between a final and a const in Dart?

For Numbers, Strings, etc, I would like to send here: https://flutter-examples.com/list-of-all-data-types-available-in-dart-flutter/

Const

From what we know from programming, a constant value is one that doesn't ever change, and if you do try to change it your code will blow up. Now, in Dart there's a little bit more to it than that. In Dart a const is a specific value that is assigned once at compile time. What this means in practice is, a const in Dart should only really hold things that are set in stone and not dynamically generated. A good example are some reusable numbers, strings, doubles, etc. Once the value is assigned at compile time, it is baked into the app code and is stored in zeros and ones. A const cannot hold any dynamically generated data, like for example a Date.now() or a `Color` widget because this value won't be known to the compiler ahead of time.

// You can do:
const a = 10;

// But this will fail
const b = DateTime.now();

// A common use case for example could be reusing a colour like so:
const myConstantColour = Color('0xFF1D1E33');

Final

So whats a final in that case? A final in Dart acts more like a const in JavaScript you know and love. A final is an immutable value which can only be assigned once at any given time. It can hold any value which is assigned once and then never changed again. It's something of a loose constant which you'll see appear in your code a lot.

Static

The post wouldn't be complete if we didn't mention the keyword static.

Used in a Class context, a static value is static to the Class. Which means in human terms that the value should be accessed statically from the Class like in this example:

class Ducky {

static String material = 'Rubber';

}

In this case, in another object the static value will be referred to through the Class itself not through the instantiated object (i.e. Ducky duckyObject = new Ducky() in this case)

Ducky.material == Rubber