Has a section called: "Have you seen this Google language, Go? How does Rust compare?"
Excerpt: "Go adopted semantics (safety and memory model) that are quite unsatisfactory." Like Null pointers, global GC, shared mutable state etc.
Has a section called: "Have you seen this Google language, Go? How does Rust compare?"
Excerpt: "Go adopted semantics (safety and memory model) that are quite unsatisfactory." Like Null pointers, global GC, shared mutable state etc.
I'm a C++ systems programmer, so I'm trying to understand some of the issues here. I'm not familiar with either language, please forgive the ignorant questions.
Null: Why is null evil? Doesn't Go use it in the Java sense of releasing a reference to the object?
Global GC: Seems more like a runtime implementation choice?
Shared mutable state: Doesn't seem so bad for someone approaching a systems programming language. I don't always want to make copies and send it over as a message to the other threads?
My higher-level point is that, perhaps these languages could do a better job of selling, differentiating, explaining themselves. I know it's hard, that's why I'm trying to help by posing my stupid questions. Btw. if they're planning to write Firefox in this, maybe the author should maintain a minimal browser written in Rust to show how the language fits its original design goals.
Global GC is definitely a language issue. It affects language semantics.
Avoiding shared mutable state does not mean making copies. If you can statically check there is no other reference you can avoid copying. Think advanced move semantics.
Global GC: It's hard to do GC without stopping the world. If different threads have different heaps, only a single thread needs to be stopped at any given time for the GC to be performed (on this thread's heap). AFAIK, Rust also supports manually managed references.
Shared mutable state: I believe that is more of a language restriction, not VM (i.e. sending messages could be implemented without copying). Simplifies debugging and makes some abstractions much easier (distributed computing in particular).
We've learned that, especially when it comes to concurrency, there really is no one model that supports everything you might want to do. Instead, the idea is to support safe, data-race-free language constructs, and to make those the easiest ones to use. Data races (and memory unsafety) are clearly marked in "unsafe" blocks, with the idea that if you find a concurrency bug in your software, you can grep for that keyword and go over those blocks only, instead of having to crawl through the entire codebase.
The same principle applies to null. You can get nullable pointers (use option<T>), but you have to declare that that's what you want. You also have to declare some strategy for handling the null case every time you use the pointer, or at least communicate your intent to fail on null via the .get() method. The vast majority of pointers in any program aren't nullable, so in practice we've found that this eliminates a lot of bugs.
> Every language is small compared to C++.
Good point. :)However, the devs are aiming to keep the language simple. They're PL experts (watching them at work is quite intimidating, actually, as someone who doesn't have a PhD in CS), but they absolutely reject the allure of the ivory tower. Note the header on the page linked in this submission:
"a safe, concurrent, practical language"
Note "practical". I've witnessed several exchanges on the mailing list where the developers attempt to excise language features. For example, in Rust, `if` is an expression rather than a statement, and thus is redundant with the `?:` ternary conditional expression syntax familiar to C-like languages (the latter was removed). Alternatively, they often acknowledge that having three types of pointers is suboptimal from a simplicity perspective, but they consistently conclude that the semantics unique to each type of pointer are valuable enough to justify the mental cost.
My colleague Dave Herman always says that language design goes through cycles: You identify a problem, add solutions to fix it, then discover that these solutions are best merged with some other ideas. The result is that, as a language evolves, complexity goes up and down. I think that we're coming off a peak of complexity and the language is going to evolve toward simplicity in the near term.
Just to name a few simple examples, removing the alias analysis pass and removing "native modules" are some simplifications that mostly have consensus at this point.