Hacker News new | ask | show | jobs
by swsieber 3734 days ago
You have a point, however, what rust enforces is more strict than what you need to adhere to in order to write a correct C program.

The proof of this is that several core concepts that are considered "safe" have "unsafe" portions that make let work. Thus, there are safe things that rust doesn't consider safe, or that rust cannot infer is safe.

5 comments

  > The proof of this is that several core concepts that 
  > are considered "safe" have "unsafe" portions
I don't understand this argument. Rust could have built those features (e.g. `Rc`) directly into the compiler itself and it wouldn't have made the language itself any more safe, and it wouldn't have made the safe bits of the language any more or less powerful.

In fact, `Rc` was once a first-class part of the language itself, and was indicated by the `@` sigil. The fact that it now lives in the standard library rather than the compiler is because library code is easier to audit for correctness than the compiler internals; to prove that the language is powerful enough to permit user-defined smart pointers and memory management primitives; and to permit alternative implementations of basic language features to be swapped in and out via custom standard libraries (which is way easier to do than forking the compiler).

> Thus, there are safe things that rust doesn't consider safe, or that rust cannot infer is safe.

That's also true for any programming language that claims to achieve safety in any sense. At some point you have to have a trusted computing base, whether it's your hardware or the standard library.

In other words, the presence of "unsafe" in the implementations of some things doesn't make Rust unsafe--if Rust is unsafe then so is every other safe language.

I think that swsieber's point was not that Rust is unsafe, but rather that Rust is too paranoid. There exist safe things that Rust will not let you do (without turning off the safety catches)!

Of course, the answer to that is still pretty much exactly what you said: it's true of every programming language that claims to achieve safety in any sense. If Rust is too restrictive then so is every other restricting language.

swsieber, according to says some guy named Gödel, every type system that is sound (and decidable) is not complete. Since decidability is kind of not optional, and most people are not okay with your type system sometimes telling you that something is okay when it's not okay, well, you're gonna have excessive constraints in your language.

Decidability actually is optional; some folks experimenting with dependent type systems are bullish on giving up decidability (allowing type checking to fail to terminate in some cases). Typechecking is already 2^(2^PROGSIZE) for, say, ML. That could easily - in theory - lead to impracticably long compilation times. Yet in practice, it doesn't. So why not go whole hog?
I'm pretty sure the answer actually is that certain things are provably safe, at least in a way that can easily be accomplished by the compiler, and some aren't (at least simply by a compiler at our current understanding). We may be able to reason about a situation and prove to our understanding that something is safe, but that doesn't always mean we can encode those rules in a deterministic and terminating way.

I imagine rust would happily extend what it considers safe if it can be determined in an effective way and if it requires additional decoration, doesn't conflict with current syntax.

> The proof of this is that several core concepts that are considered "safe" have "unsafe" portions that make let work

I think this is actually a common pattern in many different domains. For example, the OS kernel's virtual memory subsystem does many things with "unsafe" primitives -- it has direct access to page tables and can map anything anywhere -- yet it provides a "safe" abstraction of isolated process address spaces.

The way I think about it is that you have to define basic building blocks somewhere. It's not reasonable to build a static analysis that understands the N different varieties of smart pointers, and refcounting, and dynamically-checked mutability (RefCell), and custom allocators (TypedArena), and all that. It's much more elegant to separate concerns, have only raw pointers and lifetimes/borrowing built-in, and put those pieces together in "blessed" ways with all the unsafe code in one place in the library. If you try to build that understanding into the compiler instead, you're just moving the same unsafe-has-to-be-correct algorithm down one level, and unnecessarily complicating things.

> You have a point, however, what rust enforces is more strict than what you need to adhere to in order to write a correct C program.

And C enforces stricter type checking rules than what you need to adhere to in order to write a correct Python program. This is not a bad thing; having an automated assistant that can catch errors as you make them is highly useful. Rust simply pushes this to the domain of memory management and once its rules become more engrained in our development habits, I'm sure it'll be about as painless to deal with than it is to deal with type checking.

Too late to edit, so here it is in a separate post:

My point is that rust is a little more strict than C (even correct C). So even if you are a good C programmer who writes without memory leaks, you'll still probably have to battle the compiler for a bit.

Not hating on rust or its abilities - I think it's great.