Live data from Hacker News

The borrowchecker is what I like the least about Rust

viralinstruction.com

51–60 of 459 posts

Re: The borrowchecker is what I like the least about Rust

#51

Earlier quoted context omitted.

Auto-deriving Copy would also mean that there needs to be an escape-hatch: eg. Vec would auto-derive Copy.

Yes you would need an escape hatch, but your example is wrong. Vec can't be Copy, because it has a destructor. This program fails to compile: #[derive(Clone, Copy)] struct S; impl Drop for S { fn drop(&mut self) {} } fn main() {}

Oh, good point yeah; I wasn't thinking of Drop clashing with Copy, but just about the fields that make up a `Vec`.

Re: The borrowchecker is what I like the least about Rust

#52
>The first time someone gave be this advice, I had to do a double take. The Rust community's whole thing is commitment to compiler-enforced correctness, and they built the borrowchecker on the premise that humans can't be trusted to handle references manually. When the same borrowchecker makes references unworkable, their solution is to... recommend that I manually manage them, with zero safety and zero language support?!? The irony is unreal. Asking people to manually manage references is so hilariously unsafe and unergonomic, the suggestion would be funny if it wasn't mostly sad.

Indices aren't simply "references but worse". There are some advantages:

- they are human readable

- they are just data, so can be trivially serialized/deserialized and retain their meaning

- you can make them smaller than 64 bits, saving memory and letting you keep more in cache

Also I don't see how they're unsafe. The array accesses are still bounds-checked and type-checked. Logical errors, sure I can see that. But where's the unsafety?

Re: The borrowchecker is what I like the least about Rust

#53
post #33

Earlier quoted context omitted.

I've similarly thought about building a language that compiles to Rust, but handles everything around references and borrowing and abstracts that away from the user. Then you get a language where you don't have to think about memory at all, but the resulting code "should" still be fairly fast because Rust is fast (kind of ending up in the same place as Go). I haven't written a ton of Rust so maybe my assumptions of w…

Why compile to Rust for this? Many people that build transpilation languages target C directly.

A C compiler won't complain if your generated code does certain horrible things.

Re: The borrowchecker is what I like the least about Rust

#54

Earlier quoted context omitted.

Hobby language? Plenty of commercial and important software has been written in OCaml. Hell, the early versions of the Rust compiler were written in OCaml...

Maybe I’m wrong, but I only really know of Jane Street for OCaml, meanwhile FAANG all has at least some rust code. Also I would argue the rust compiler started as a hobby project

Also Bloomberg: https://news.ycombinator.com/item?id=28278553

Re: The borrowchecker is what I like the least about Rust

#55

Earlier quoted context omitted.

Auto-deriving Copy would also mean that there needs to be an escape-hatch: eg. Vec would auto-derive Copy.

Yes you would need an escape hatch, but your example is wrong. Vec can't be Copy, because it has a destructor. This program fails to compile: #[derive(Clone, Copy)] struct S; impl Drop for S { fn drop(&mut self) {} } fn main() {}

Actually; I'm not sure I'm wrong. If Copy was automatically derived based on fields of a struct (without the user explicitly asking for it with `#[derive(Copy)]` that is, as the parent comment suggested the OP is asking for), then your example S and the std Vec would both automatically derive Copy. Then, implementing Drop on them would become a compile error that you would have to silence by using the escape hatch to "un-derive" Copy from S/Vec.

So, whenever you wanted to implement Drop you'd need to engage the escape hatch.

Re: The borrowchecker is what I like the least about Rust

#56
post #8

This post pretty much completely ignores the advantages of the borrow checker. I'm not talking about memory safety, which is it's original purpose. I'm talking about the fact that code that follows Rust's tree-style ownership pattern and doesn't excessively circumvent the borrow checker is more likely to be correct . I don't think that was ever the intent behind the borrow checker but it is definitely an outcome. So…

He's not ignoring them. The point of the article is that the author doesn't experience those things as concrete advantages for them. Like sure, there are advantages to those things, but the author says he doesn't feel it's worth the trouble in his experience for the sorts of code he's writing.

One good RCE in production could alter this perception quite a bit. "The mosquito repellent is useless, I see too few mosquitos around me anyway."

Re: The borrowchecker is what I like the least about Rust

#57

I don't use Rust much, but I agree with the thrust of the article. However, I do think that the borrowchecker is the only reason Rust actually caught on. In my opinion, it's really hard for a new language to succeed unless you can point to something and say "You literally can't do this in your language" Without something like that, I think it just would have been impossible for Rust to gain enough momentum, and also…

This is also somewhat backed up by the fact that OCaml (to my understanding) is basically GC Rust without a borrow checker, and yet it’s basically a hobby language.

I think there are two other big differences that also helped Rust become popular:

* Rust has a C++-flavored syntax, but OCaml has a relatively alien ML-flavored syntax.

* Rust has the backing of Mozilla, but I don't think OCaml had comparable industry backing. (Jane Street, maybe?)

Re: The borrowchecker is what I like the least about Rust

#58
post #7

Earlier quoted context omitted.

See Rust's golden rule: https://steveklabnik.com/writing/rusts-golden-rule

This seems to be a golden rule of many languages? `return 3` in a function with a signature that says it's going to return a string is going to fail in a lot of places, especially once you exclude bolted-on-after-the-fact type hinting like what Python has. It's easier to "abuse" in some languages with casts, and of course borrow checking is not common, but it also seems like just "typed function signatures 101". Are…

In C++, the signature of a function template doesn't necessarily tell you what types you can successfully call it with, nor what the return type is.

Much analysis is delayed until all templates are instantiated, with famously terrible consequences for error messages, compile times, and tools like IDEs and linters.

By contrast, rust's monomorphization achieves many of the same goals, but is less of a headache to use because once the signature is satisfied, codegen isn't allowed to fail.

Re: The borrowchecker is what I like the least about Rust

#59

Earlier quoted context omitted.

The whole point is that `Id` doesn't have a destructor (it's purely stack-allocated); that is, conceptually it _could_ be `Copy`. A more precise way to phrase what he's getting at would be something like "all types that _can_ implement `Copy` should do so automatically unless you opt out", which is not a crazy thing to want, but also not very important (the ergonomic effect of this papercut is pretty close to zero).

Auto-deriving Copy would also mean that there needs to be an escape-hatch: eg. Vec would auto-derive Copy.

Copy is already banned for any type that directly or indirectly contains a non-Copy type, and Vec contains a `*const T`, which is not Copy.

Re: The borrowchecker is what I like the least about Rust

#60

Earlier quoted context omitted.

Ah I see. > A more precise way to phrase what he's getting at would be something like "all types that _can_ implement `Copy` should do so automatically unless you opt out", which is not a crazy thing to want, From a memory safety PoV it's indeed entirely valid, but from a programming logic standpoint it sounds like a net regression. Rust's move semantics are such a bliss compared to the hidden copies you have in Go (…

I think you are misunderstanding what Copy means, and perhaps confusing it with Clone. A type being Copy has no effect on what machine code is emitted when you write "x = y". In either case, it is moved by copying the bit pattern. The only thing that changes if the type is Copy is that after executing that line, you are still allowed to use y.

I'm not misunderstanding. Ore confusing the two. Copy: Clone.

Yes when an item is Copy-ed, you are still allowed to use it, but it means that you now have two independent copies of the same thing, and you may edit one, then use the other, and be surprised that it hasn't been updated. (When I briefly worked with Go, junior developers with mostly JavaScript or Python experience would fall into this trap all the time). And given that most languages nowadays have pointer semantics, having default copy types would lead to a very confusing situation: people would need to learn about value semantics AND about move semantics for objects with a destructor (including all collections).

No thanks. Rust is already complex enough for beginners to grasp.

Post reply on HN