Live data from Hacker News

The borrowchecker is what I like the least about Rust

viralinstruction.com

381–390 of 459 posts

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

#381

Earlier quoted context omitted.

Flamebait? It's literally what the designers of Golang said publicly about the background of prospective developers, and how that constrained the language design: "The key point here is our programmers are Googlers, they’re not researchers. They're typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They're not capable of understanding a brilliant lang…

That's one interpretation but I think Pike was using a sarcastic meaning for brilliant. I think he's saying that he wants to mentor people to become programmers, not to learn a difficult, sublime language. It's like when a top scientist tells you they're not smart enough to understand what's going on in some part of his field. It's not necessarily a compliment.

Feel free to listen to the context at https://learn.microsoft.com/en-us/shows/lang-next-2014/from-... around 20:40 to 21:10. It's pretty clear that it's a serious quote and not "sarcastic" at all. Least of all about research languages since Pike mentions CSP at length and how to make concurrency be not "scary" to prospective users - overall, it seems that he's talking about a real constraint he's facing. In the same talk he's even apologetic for not preventing data races in the language, since it would have involved too much complexity.

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

#382

Earlier quoted context omitted.

Ummm. Yeah it is. I'm sure you can come up with some cases where the impact of the bugs is roughly equivalent, but generally speaking, UB is a terrible class of bug. For example, if the aho-corasick crate accidentally tries to look up a dangling state node, you'll get a panic. But if this were UB instead, that could easily lead to a security problem or just pretty much anything... because behavior is undefined . So g…

Author here. In scientific computing, there isn't much of a security implication of UB, and the most dangerous kind of error are when your program silently computes the wrong thing. And that is especially likely when you use indices manually. You could say that UB enables all behaviour, including silently wrong answers, and you'd be right. But it's more likely to crash your program and therefore be caught. Most impor…

> And that is especially likely when you use indices manually.

But that is never the recommendation Rust practitioners would give for graph data structures. One would instead recommend using a generational arena, where each index holds their "generation". The arena can be growable or not. When an element is removed from the arena it gets tombstoned, marked as no longer valid. If a new value reuses a tombstoned position, its generation changes. This shifts the cost of verifying the handle is correct at the read point: if the handle corresponds to an index with a tombstone sentinel or has a different generation, the result of the read operation is None, meaning the handle is no longer valid. This is much better than the behavior of pointers.

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

#383
post #191
post #78

Earlier quoted context omitted.

> The trouble is that you've re-created dangling pointers That's true, but as a runtime mitigation, adding a generational counter (maybe only in debug builds) to allocations can catch use-after-frees. And at least it's less likely to be a security vulnerability, unless you put sensitive information inside one of these arrays.

> adding a generational counter (maybe only in debug builds) to allocations can catch use-after-frees. At the cost of making the use of the resulting heap significantly slower and larger than if you just wrote the thing in Java to begin with, though! The resulting instrumentation is likely to be isomorphic to GC's latency excursions, even. This is the biggest issue that bugs me about Rust. It starts from a marketing…

> It starts from a marketing position of "Safety With No Compromises"

Since such a tradeoff is not possible (full safety for free?!) I doubt there's any such marketing.

> The world is filled with very reasonably compromised memory-safe runtimes that are excellent choices for your new system.

Bringing a whole managed runtime just to handle a single structure with cycles in your program is not reasonable.

There's no problem with using a simple GC for a tiny part of an otherwise manually managed program just how there's no issue in managing memory manually for a small, but performance sensitive part of your GC managed program.

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

#384

Earlier quoted context omitted.

Author here. In scientific computing, there isn't much of a security implication of UB, and the most dangerous kind of error are when your program silently computes the wrong thing. And that is especially likely when you use indices manually. You could say that UB enables all behaviour, including silently wrong answers, and you'd be right. But it's more likely to crash your program and therefore be caught. Most impor…

You're engaging in a motte-and-bailey fallacy. Your motte is your much more narrow claim about Rust's advantages in a context where you claim not to care about undefined behavior as a class of bugs more severe than logic errors. And you specifically make this claim in an additional context where a GC language is appropriate. That's an overall pretty easy position to defend, and if that were clearly the extent of it,…

> I don't think it's possible to write a tool like ripgrep with its performance profile in a GC language.

I think it is possible to make a language that has both a GC and a borrow checker, treating the GC types as a third level next to the stack and the heap, where complex referencial cycles can bé promoted to the GC, but the defaults push you towards fast execution patterns. Don't know if such a language would be successful in finding its niche. The only way I could see that, is of a non-gc mode could be enforced so that libraries can be written in the more restrictive, faster by default mode, while being consumed by application developers that have less stringent restrictions. This is no different in concept than Python libraries implemented in native languages. Making it the mode be part of the same language could help with prototyping pains: write with the GC and then refactor once at the end after the general design is mostly found.

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

#385
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…

There are languages with full inference that break this rule.

Moreover, this rule is more important for Rust than other languages because Rust makes a lot of constraints visible in function signatures.

But the most important purpose of the rule is communicating that this is a deliberate design decision and a desireable property of code. Unfortunately, there's an overwhelming lack of taste and knowledge when it comes to language design, often coming from the more academic types. The prevailing tasteless idea is that "more is better" and therefore "more type inference is better", so surely full type inference is just better than the "limited" inference Rust does! Bleh.

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

#386

Earlier quoted context omitted.

But why add a language feature (and a new symbol, even!) when by definition you can always fix the issue by shadowing the original variable and pointing it at the new location? At most, this calls for a change in compiler diagnostics to add a hint in cases that are trivially fixable.

There are scenarios where retrieving the just-inserted value without first cloning it isn't possible. E.g.: when inserting a value into a non-empty hashset and then needing it again immediately. But yeah... that's a bit of a contrived example and can be solved by a simple change to the insert function without specialised support from the language.

It sounds like you'd want the entry API: https://doc.rust-lang.org/std/collections/struct.HashMap.htm...

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

#387

Earlier quoted context omitted.

You're engaging in a motte-and-bailey fallacy. Your motte is your much more narrow claim about Rust's advantages in a context where you claim not to care about undefined behavior as a class of bugs more severe than logic errors. And you specifically make this claim in an additional context where a GC language is appropriate. That's an overall pretty easy position to defend, and if that were clearly the extent of it,…

> I don't think it's possible to write a tool like ripgrep with its performance profile in a GC language. I think it is possible to make a language that has both a GC and a borrow checker, treating the GC types as a third level next to the stack and the heap, where complex referencial cycles can bé promoted to the GC, but the defaults push you towards fast execution patterns. Don't know if such a language would be su…

> I think it is possible to make a language that has both a GC and a borrow checker, treating the GC types as a third level next to the stack and the heap, where complex referencial cycles can be 'promoted to the GC'

It's doable but there are a few issues with that whole idea. You need the ability to safely promote objects to GC-roots whenever they're being referenced by GC-unaware code, and demote them again afterwards. And if any GC object happens to control the lifecycle of any heap-allocated objects, it must have a finalizer that cleans them up RAII style to avoid resource leaks.

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

#388
post #70

One of his examples of a borrow checker excess: struct Id(u32); fn main() { let id = Id(5); let mut v = vec![id]; println!("{}", id.0); } isn't even legit in modern C++. That's just move semantics. When you move it, it's gone at the old name. He does point out two significant problems in Rust. When you need to change a program, re-doing the ownership plumbing can be quite time-consuming. Losing a few days on that is…

> When you move it, it's gone at the old name . (Emphasis mine.) I just had a thought! It might make languages like Rust more ergonomic if movement could also update the reference to the new location so that moving a local variable into a container could also update the variable to reference the target also. The "broken" example can be trivially fixed: fn main() { let id = Id(5); let mut v = vec![id]; let id = v[0].0…

On its own, that doesn't sound like the worst idea. But at least in Rust, one problem is that further modifying the container will immediately invalidate the new reference, as will reading from the container if you get a mutable reference. References into containers are temperamental in general, unless you can handle them in smaller scopes that are unaware of the larger container.

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

#389
post #353
post #273

Earlier quoted context omitted.

I worked with C# for a decade and it's become a really great general purpose language. I'd still prefer never to work with it ever again after having worked with Go. This isn't for technical reasons at all, but because Golang is so easy to work with for "people reasons". There are brilliant parts of Go, but the only thing I find myself missing in other languages is the simplistic module isolation, where every folder…

> I hate the fact that they didn't want runtime assertions as an example, So you hate writing: if (something != 1) { panic("oh no!") } vs assert(something != 1, "oh no!") ? Reminds me of people complaining about Python's significant indentation. If that's what you're complaining about, you have nothing to complain about.

I think your point is fair as you can do runtime safety in Go by wrapping Panic, but that's not exactly what Panic is meant to be used for. I guess it's more of a intent vs syntax thing, aside from the part where Panic can be Recover()ed.

You're taking it out of a context of me praising Golang, however, and while I do hate the fact that they didn't just do runtime assertions, it's not like I dislike Go as a whole because of it.

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

#390

Earlier quoted context omitted.

>If it’s Rust, I can just do stuff and I’ve never broken anything. This is not true. Case and point- Java. Many times simpler than Rust, and large codebases are as horrible as C++ ones.

I have two primary complaints about Java, relative to Rust: 1. NullPointerException. I get some object with a bunch of fields and I don’t know which of them are null. In Rust I am given a struct, and usually the fields aren’t an Option unless they need to be. 2. Complicated design patterns with inheritance. Maybe it’s more of a problem with the culture/ecosystem than Java the language. But Rust doesn’t have inheritan…

The point is that programmers are ultimately responsible for clean code. You can write very good C code that is very easy to debug. Languages don't really matter for this.
Post reply on HN