5 ms·
TLDR: - I see 'unsafe' everywhere; - Async is problematic, colored functions! - Community is nice, but it won't be forever, RIIR people are annoying; Conclu
by jgilias 5y ago
TLDR:
- I see 'unsafe' everywhere;
- Async is problematic, colored functions!
- Community is nice, but it won't be forever, RIIR people are annoying;
Conclusion: I prefer GCed languages with default async runtimes.
- Animats 5y agoI see too much "unsafe" in libraries, too. I write Rust code with no "unsafe", and it's hard. Sometimes you have to go back and do a major redesign because you painted yourself into a corner. Sometimes you take a performance hit. Some crates with "unsafe" that shouldn't have to have it: * priority-queue ("Improved performance using some unsafe code in the implementation.") * serde-json, uuid (takes in byte strings and makes UTF-8, without being strict enough about types.) * crossbeam-channel (lock-free code which does atomic operations on small structs by coercing them into numeric types for which atomic operations are supported.) There are a relatively small number of pain points which lead people into unsafe pure Rust. The language needs an effort to hammer them out. (I'm not talking about foreign function interfaces to legacy C/C++code; that's never going to be safe, but can become obsolete.) Async is problematic, colored functions! The web backend crowd wants to write Javascript-type code in Rust. This is a bad fit. As I've said before, web backend stuff with huge numbers of connections should be written in Go. Goroutines and garbage collection are a better fit to that problem, because there's only one thread-like construct and it's both low-overhead and preeemptable. The Rust approach complicates code that's changed frequently ("agile", right?). You have to be careful about what's async, what's a thread, what's non-threadable async, and what runs more than 100us without giving up control. Too much engineering is required for routine web server stuff. Go handles that all automatically. I'd like to see two hard problems addressed in the language: backpointers and lock order. You can do backpointers with strong reference counts forward and weak reference counts backwards, but now you're reference counting everywhere. If you screw up and mutably borrow twice, you get a run-time error when you call ".borrow_mut()". The borrow checker doesn't look at reference counted items. Single owner with backpointer ought to be analyzable statically, although it's hard to do. The basic constraint is that the call chain can't pass through the same mutably borrowed struct twice. That is, it's loop-free. There are additional issues about keeping forward and back pointers in sync, but those are easier than statically detecting a double borrow. Lock order is a closely related problem. You can't lock the same thing twice in the same thread. Again, this is a constraint that the call chain can't pass through the same lock twice. Also, locks must be ordered, so that you don't deadlock by locking A, then B in one thread, while locking B, then A in another. Again, a constraint on the call chain. Both of those are hard theoretical problems, and work is underway on addressing the first one, at least. Not having a sound solution to these problems leads to hack workarounds. There's other little stuff to gripe about, but those are the big items that lead either to serious bugs or major rework.
- jgilias 5y agoYour points are much more meaningful than what's expressed in the article. Regarding unsafe though. In other non-GC languages (C/C++, say) there's no keyword for `unsafe` as that is the default state. And that's fine. People generally don't have too much trouble trusting library authors to mostly do the right thing. In Rust the places where you have to defer to human judgement are clearly marked, and I see that as a net benefit over status quo irrespective of how much `unsafe` is actually used in one or another library. GC-ed languages are a different matter altogether. They sit on a different point in the trade-offs graph in my opinion. However, pointing out that the design trade-offs that have been taken in Rust may not be ideal for one or another use case is very much a valid thing to say!