Hacker News new | past | comments | ask | show | jobs | submit login

(White on black in Courier? Please.)

After a year of writing Rust for a client for a virtual world, some comments.

For this problem, the server is constantly feeding you UDP packets full of changes to the scene, and you're constantly fetching assets from other servers using HTTP. All this has to happen while updating the screen at 60FPS or so. It takes several CPUs and a GPU working hard to show a detailed 3D world properly.

* Safety is a big deal. I haven't had to go into a debugger in the last year. That's a huge win.

* There's a lot of concurrency involved, and being free of race conditions is a big help. Rust does not help with deadlock avoidance, though. That's the next frontier in concurrency - static deadlock avoidance analysis. There are people working on this for Rust, but it's a hard problem.

* Rust has a big problem with certain data structures. In particular, if you have a single ownership tree, you cannot get from a child to a parent. If you want to have backlinks, you have to reference count everything. The language needs something like "single owner with weak backlink, made safe at compile time". That's a hard problem. I keep ending up with refcounts forward and weak refcounts backwards. With refcounts, if you borrow something twice, you get a panic at run time. The compiler cannot catch those at compile time. So borrowing has to be very short term.

* Rust wants functional programs. If what you're doing fits into that model, everything goes smoothly. When there's a lot of state, it's harder. The state here is a whole 3D scene, so it's inherent in the task. In server side web stuff, most of the state is in the database, so the application programmer doesn't have to deal with maintaining its consistency.

* You can paint yourself into a corner with data structures. Figuring out where you need reference counts, where you need locks, and where you need interior mutability has to be right. And you can run into problems such as "that struct can't have the 'send' attribute because it has an element which, deep down, contains a reference count". Make a mistake and rework is difficult. Data structure design is a puzzle-solving problem.

* "Async" has most of the same locking restrictions as threads. It's not like Javascript, where you never explicitly lock. Unless you have some huge number of threads, async isn't much of a win. It's really for the use case of a server with a huge number of slow clients. You probably shouldn't be using Rust for that anyway. That's Go's ideal use case.

I have some arguments with the Rust designers. But really, it's a big advance over C++. It's not a panacea. As I keep saying, do your web server stuff in Go. Go has a more user friendly memory allocation model, a more user friendly threading model, and well-exercised libraries from Google for things web servers do. Rust is for the hard problems.




> being free of race conditions is a big help

Maybe this is a nitpick, but the need to say it suggests you might not understand something important. (Safe) Rust has data race freedom not freedom from race conditions. The most likely reason to muddle those is not knowing what the difference is, which is important because race conditions are an unavoidable phenomenon in computer systems (and indeed the real world) whereas data races are something very strange and difficult to reason about.

If you put the cat out the front door, then walk to the kitchen and close the kitchen door, you can't be certain the cat is still outside, it might have run around and back inside. That's a race condition. Rust doesn't inherently care about those, so if you do then you need to program carefully to handle them. Data races aren't like that, they don't have a clear real world analog, perhaps they're as if you could discover that sometimes while you're putting the cat outside, somebody else is simultaneously putting the same cat inside your house - except, that doesn't make much sense. Nor do data races, which is why it's important that Rust prevents them while many languages just make that your problem.


> Rust has a big problem with certain data structures. ... The language needs something like "single owner with weak backlink, made safe at compile time". That's a hard problem.

GhostCell and its variations (QCell, LCell etc.) are meant to address this without resorting to Unsafe Rust. But it's a bit of a hack so far, and yes it would be nice to have a more elegant, language-level solution.


GhostCell is interesting. I need to try that in some test cases. Apparently you can make data structures with backlinks, but the whole structure may be immutable once made. You need to change at least two links as an atomic operation for that. It's hard to express that via a type system hack.

Then there's the problem of you got there by following links, and now you want to mutate something. Chasing links is fine if they're read only, but if they're mutable, you have to make sure you don't have a loop of mutable references. Again, this is a non-local analysis kind of problem.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: