What if "const" was opt-out instead of opt-in?

161 points nikitarevenco 37 comments

What if everything was const by default in Rust?

Currently, this is infeasible. However, more and more of the standard library is becoming const.

Every release includes APIs that are now available in const. At some point, we will get const traits.

Assume everything that can be marked const in std will be, at some point.

Crates are encouraged to use const fn instead of fn where possible. There is even a clippy lint missing_const_for_fn to enforce this.

But what if everything possible in std is const? That means most crates could also have const fn for everything. Crates usually don't do IO (such as reading or writing files), that's on the user.

Essentially, if you see where I am going with this. When 95% of functions in Rust are const, would it not make more sense to have const be by default?

Computation happens on runtime and slows down code. This computation can happen during compilation instead.

Rust's keyword markers such as async, unsafe, mut all add functionality. const is the only one which restricts functionality.

Instead of const fn, we can have fn which is implicitly const. To allow IO such as reading to a file, you need to use dyn fn instead.

Essentially, dyn fn allows you to call dyn fn functions such as std::fs::read as well as fn (const functions, which will be most of them)

This effectively "flips" const and non-const. You will have to opt-in like with async.

At the moment, this is of course not possible.

  • Most things that can be const aren't.
  • No const traits.
  • Const evaluation in Rust is very slow:

Const evaluation uses a Rust Interpreter called Miri. Miri was designed for detecting undefined behaviour, it was not designed for speed. Const evaluation can be 100x slower than runtime (or more).

In the hypothetical future there will be a blazingly fast Rust Just-in-time (JIT) compiler designed specifically for evaluating const code.


But one day, maybe we will have all of those things and it would make sense to flip the switch on const.

This can even happen without Rust 2.0, it could technically happen in an edition where cargo fix will do the simple transformation:

  • fn -> dyn fn
  • const fn -> fn

With a lint unused_dyn which lints against functions that do not require dyn fn and the function can be made const: dyn fn -> fn