News for hackers. Stuff that matters.
Re:Linux kernel in-tree Rust support by pornel on Saturday July 11, 2020 @09:25AM (#23802041)
• Rust is an ML-family language dressed in a C-family syntax to look palatable to existing systems programmers. It's a byproduct of the C++ world only to the extent that it has to work on the CPU architectures and operating systems influenced by C and C++.

• Rust is mainly based on established research and existing languages from 80s and 90s. It's a distilled version of these, not a prototype.

I recommend checking out the first pitch deck for Rust: http://venge.net/graydon/talks/intro-talk-2.pdf

Re:Linux kernel in-tree Rust support by umanwizard on Saturday July 11, 2020 @10:02AM (#23802278)
RAII-based memory management without GC, and the concept of ownership vs. borrowing are very C++-inspired concepts. The borrow checker, which is the main innovation of Rust, is automated checking of things C++ programmers spend a lot of effort thinking about.

I think the influence of C++ is much more than just the syntax.

Re:Linux kernel in-tree Rust support by adimitrov on Saturday July 11, 2020 @10:48AM (#23802575)
Isn't this more of an artifact of our memory architecture and the way we (de-)allocate memory? In that sense, the C++ flying-by-the-seat-of-your-pants approach and Rust's borrow checker solve the same problem, and I'm sure a lot of C++ insight has made it into the ideas behind the borrow checker, but I'm not sure that makes Rust in a way derivative of ideas extant in C++-land.

To me, the borrow checker just feels like an additional type layer I have to reason and think about. In that sense, my thinking when reasoning about lifetimes in Rust is a lot more along the same lines I do in Haskell than something I would be doing in C++ (which I refuse to code in, I'm not capable of writing secure C/++ code.)

Re:Linux kernel in-tree Rust support by creato on Sunday July 12, 2020 @12:26AM (#23808802)
I think the programs that fit neatly into Rust's borrow checking patterns are the same ones that fit neatly into C++(11)'s approach to managing object lifetimes (move/value semantics).

The question is what happens when programs don't fit those patterns. Inevitably in any large real world application, there are some objects with lifetimes that need to be managed carefully and don't match conveniently with some sort of scope in a program.

With C++, this is where one would use std::shared_ptr, or something else. In rust, there's Rc. But either way, you've now stepped into a territory where object lifetimes and bugs can be messy.

Re:Linux kernel in-tree Rust support by roca on Sunday July 12, 2020 @02:02AM (#23809220)
I do not find reference counting problematic in practice. In Rust you have to go out of your way to introduce interior mutability in refcounted values, which discourages problematic patterns.

I find that in most cases where ownership patterns don't fit the Rust model, you can abstract the problematic parts into some kind of collection type and hide them in its own crate --- or better still, find an existing crate that does what you need.

The only remotely common case that still doesn't get handled well, in my experience, is the self-referential struct pattern --- when a value needs to contain references to other parts of the same value.

Re:Linux kernel in-tree Rust support by zozbot234 on Sunday July 12, 2020 @07:02AM (#23810477)
> The only remotely common case that still doesn't get handled well, in my experience, is the self-referential struct pattern --- when a value needs to contain references to other parts of the same value.

There's a basic reason for that, namely you can't memcpy a self-referential structure while keeping desired semantics. Rust now has a Pin<> feature to mark data that should not be moved in memory, but its use is still unintuitive and IIRC requires unsafe. In many cases one should perhaps avoid references to self-addresses entirely; often they can be replaced by indexes and/or offsets.

Re:Linux kernel in-tree Rust support by cesarb on Sunday July 12, 2020 @08:34AM (#23810864)
> There's a basic reason for that, namely you can't memcpy a self-referential structure while keeping desired semantics.

You actually can! For instance, consider a struct with two fields: a Vec<T>, and a &T which references one of the elements of the Vec. Moving the struct (which does the memcpy) does not reallocate the Vec, so the reference in the &T would still be valid. But as far as I know there's no way to represent that in safe Rust; the &T in the struct requires a lifetime, and there's no way to represent "the lifetime of the other field" or even "the lifetime of the struct itself" (something like &'self T).

Yeah, you can use an index in my example (replacing the &T by an usize, and looking up on the Vec every time), but it's not a perfect replacement. A reference would always be valid (and always pointing to the same element), while an index can become invalid if the Vec is truncated, or point to a wrong element if an element is inserted or removed before it in the Vec.

Re:Linux kernel in-tree Rust support by roca on Sunday July 12, 2020 @08:02PM (#23815808)
Right, I know what the reason is, but that doesn't stop it from being a problem.
Re:Linux kernel in-tree Rust support by tjoff on Saturday July 11, 2020 @10:41AM (#23802524)
Maybe that has more to do with almost everything new have been garbage collected for the last decades (and that is such a tragedy) and less to do with C++.

It is a low-level programming language after all. Not being explicit about memory would be a bad thing (it almost always is).

Re:Linux kernel in-tree Rust support by umanwizard on Saturday July 11, 2020 @11:07AM (#23802704)
I was under the impression that RAII specifically (as opposed to manually calling malloc and free by hand) was an innovation of C++, but I could be wrong.
Re:Linux kernel in-tree Rust support by pjmlp on Saturday July 11, 2020 @12:26PM (#23803316)
Ada and Object Pascal also have it.
Re:Linux kernel in-tree Rust support by tjoff on Saturday July 11, 2020 @11:49AM (#23803052)
Don't know, but the concept is very useful and has found its way into many languages, such as thr using statement in C#.

It is just that it is typically more useful/powerful in languages that lack a GC (doesn't necessarily need to be that way though, but my impression).

Re:Linux kernel in-tree Rust support by pjmlp on Saturday July 11, 2020 @05:40PM (#23806290)
C# using is Common Lisp's with-....
Re:Linux kernel in-tree Rust support by bad-apple on Saturday July 11, 2020 @11:11AM (#23802733)
> RAII-based memory management without GC, and the concept of ownership vs. borrowing are very C++-inspired concepts.

Why are you crediting C++ for an idea that is probably much older than it?

Re:Linux kernel in-tree Rust support by pjmlp on Saturday July 11, 2020 @12:31PM (#23803357)
Because it was C++ that made it mainstream.
Re:Linux kernel in-tree Rust support by verdagon on Saturday July 11, 2020 @12:54PM (#23803543)
I'd love to know where C++ got it from, but I can't find it. Any ideas?
Re:Linux kernel in-tree Rust support by smabie on Saturday July 11, 2020 @02:25PM (#23804412)
I think that's how it started out (and the compiler was first written in Ocaml), but the language has largely abandoned that heritage: the C++ camp is squarely in charge.

In the beginning, I feel like Rust aimed to be a general purpose language, but not anymore. Really the only reason why anyone would consider Rust for a project is if GC was unacceptable. And the amount of complexity in the language just to avoid that is truly staggering.

There aren't that many situations where GC can't be tolerated (and I think some would argue there are zero situations), so I don't actually see Rust as a particularly useful language, and certainly not one in the ML tradition.

Moreover, most zero allocation C code is a total lie. These code bases are littered with arena based allocator that burden the project with all the problems of GC and none of the benefits.

GC works for operating systems, they work for hard real time systems, they work for mostly everything except severely constrained embedded systems.

Re:Linux kernel in-tree Rust support by roca on Saturday July 11, 2020 @05:04PM (#23805964)
We have a 170K line project written in Rust (https://pernos.co). I've written a lot of C++ in the past, but also Java and other things (I've been programming for nearly 40 years now), so I'm familiar in developing with and without GC. Pernosco is mostly a server app that could use GC. I'm happy with the choice of Rust.

> And the amount of complexity in the language just to avoid that is truly staggering.

In terms of day-to-day coding this isn't my experience. Once in a while I have tricky ownership problems to resolve, but most of the time I get by just fine without thinking much about the ownership model.

In exchange we don't have to think at all about GC tuning or object recycling, we get RAII, we get to use affine types to encode typestates, and we get easy parallelism. I'm happy about this trade.

As you can see when I started this thread I am far more concerned about build times than I am about the cognitive overhead of ownership and lifetimes.

Re:Linux kernel in-tree Rust support by nilkn on Saturday July 11, 2020 @05:07PM (#23805997)
I have to say my experience with the language has just been very different from this. It absolutely feels like a general-purpose language to me. I actually prefer Rust over Python, as I find the language simpler to use and anywhere from 10-100x faster (if not much more than that in some cases). cargo is much better than pip, and the Rust compiler is much smarter about guiding me than something like mypy.

Maybe I'm unusual in some way, but I do not find Rust hard to use once you've learned the language. You say the complexity to avoid a GC is staggering, but it seems straightforward to me. You have to appease the borrow checker, and you need to learn about some tools like Rc, Arc, Cell, etc., that provide interior mutability. Other than that, the language has been an absolute pleasure and dream to use.

I tend to write Rust the way I write Haskell, not the way I write C++. I start by sketching out all the types that I need to model the problem space at hand. This can be done almost 1:1 with Haskell in many cases. Then I start filling in the implementation, getting me from "input" types to "output" types and only very rarely running into any kind of issue with the borrow checker. Of course, instead of using immutable data structures (as is common in Haskell), I use mutable ones in Rust. The compiler guides me the entire way, and often it feels like an entire program writes itself.

As for GCs, I almost never want one. Performance matters in almost everything I write these days, and faster is always better. Rust is so easy to write once you learn it that I see no reason to accept a GC in 2020 and beyond for any software where performance matters. I do not write software for severely constrained embedded systems. I mostly write real-time backend services that process data or handle large numbers of clients. I could tolerate a GC in much of this, but there's no reason to in a world where Rust exists, and everything is faster, more responsive, and considerably easier to reason about as a result. A few years ago, I would've used a mixture of C++ and Go. Now, I'd just use Rust for all of it.

Re:Linux kernel in-tree Rust support by pcwalton on Sunday July 12, 2020 @12:59PM (#23812781)
> There aren't that many situations where GC can't be tolerated (and I think some would argue there are zero situations)

Those people would be wrong. As an extreme example: GPU programming, where GC is essentially impossible due to the architecture.