stacks-network / stacks-core

The Stacks blockchain implementation
https://docs.stacks.co
GNU General Public License v3.0
3k stars 659 forks source link

Rust Style: Migrate away from Lifetime Parameters in favor of Smart Pointers #3333

Closed gregorycoppola closed 1 year ago

gregorycoppola commented 1 year ago

Is your feature request related to a problem? Please describe. Rust is an amazing programming language that introduces clever features to prevent many classes of bugs through static analysis at runtime.

But:

The drawbacks of lifetime parameters are:

Describe the solution you'd like We should migrate away gradually from the use of lifetime parameters, replacing these wherever possible with smart pointers (Box, Rc, Arc).

Describe alternatives you've considered Some discussion of alternatives in the particular case is here:

Nevertheless, for the reasons discussed, I still request we reduce the use of lifetime parameters in general.

Additional context This proposal started when I wanted to justify the decisions in:

jcnelson commented 1 year ago

Absolutely not. The whole reason to use Rust's lifetime parameters is to enable the compiler to prove the absence of memory safety violations and data race conditions. Replacing lifetime parameters with smart pointers defers all of these compiler checks to runtime crashes, which means users suffer.

lifetime parameters make hard or impossible to things that would be possible and easy in C++, Scala or Java

Scala and Java are garbage-collected, so comparing Rust to them is apples to oranges. Rust does not have a garbage collector.

C++ isn't exactly well-known for its ability to empower developers to write secure, correct programs that are memory safe and free of data races. Just the opposite, in fact.

no other language has lifetime paramters, and so engineers are not already familiar/expert with them

Learning Rust is a very surmountable challenge. Neither @kantai nor myself knew Rust when we started Stacks 2.0, initial lack of familiarity is not an excuse. In fact, I don't think anyone at Hiro knew Rust.

Moreover, having written lots of software in C and C++ over my professional lifetime (which is 20+ years), I can say from experience that Rust's lifetime parameters are a godsend. They enable me to offload thinking about memory safety and data races -- two notoriously-difficult things to get right -- to the compiler, which is far less likely to make mistakes in its reasoning than I am.

all type parameters increase complexity, and lifetime parameters are type parameters

The absence of these parameters increase complexity. Parametric types remove code duplication in the source code, and lifetime parameters free you from spending countless person-hours chasing down hard-to-reproduce memory faults.

So no -- we will keep using lifetime parameters and parametric types where appropriate. We will not defer to runtime that which can be checked at compile time, we will not duplicate code if we can help it, and we will not defer to humans that which can be solved with a computer.