News for hackers. Stuff that matters.
Re:Rust 1.63 by ydnaclementine on Thursday August 11, 2022 @12:08PM (#32427823)
What is everyone building in rust, and how do the killer rust features (mentioned in other comments) help you?

I'm not anti rust in any way, it's more of having limited time and so many languages problem. But I'm interested in the types of problems rust is good for, so I could consider it if/when I encounter them

Re:Rust 1.63 by ekidd on Thursday August 11, 2022 @12:30PM (#32428183)
I've built a fair amount of production software in Rust. The best features are:

- Rust is naturally pretty fast, on the rough order of C++ in many cases. Even unoptimized programs tend to be very snappy (as long as you remember to compile in release mode and buffer I/O).

- Rust tends to warn me if I make a dumb mistake, rather than having my program mysteriously corrupt memory at run-time.

- Rust has very nice support for portable CLI applications, both in the standard library and in third-party libraries.

- With a bit of extra work, I can usually deliver a single, statically-linked Linux binary. Go is even better at this, but Rust does it well.

- It turns out the "algebraic data types", what Rust calls "enum" and "match", are just a really nice way to write down every possible "case" or "state" of some value. If a piece of software involves hundreds of special cases, Rust allows me to think about them clearly.

- Rust has surprisingly good third-party libraries for many things. (Not everything.)

- Multithreaded Rust apps are a dream.

Cons:

- Rust forces me to keep track of whether things live on the heap or the stack, whether I'm passing them by value or reference, and so on. This is good when I want performance, but for other kinds of code, it's just a "cognitive tax."

- Rust's learning curve is higher than Go, but arguably lower than C++. This is especially true if you've either never worked with stack/heap/pointers before.

- Rust tends to favor "mostly functional" architectures over "mutable objet soup" architectures. This pushes you to use less-familiar designs for games and GUI libraries, for example.

Re:Rust 1.63 by cassepipe on Thursday August 11, 2022 @08:11PM (#32433383)
> Rust's learning curve is higher than Go, but arguably lower than C++. This is especially true if you've either never worked with stack/heap/pointers before.

I tried to learn Rust when I only knew Python and had not CS education, I gave up rather quickly. Then I did some projects in C and later on C++, and now I understand Rust. Because I understand what are the problems it tries to solve. Imho only after you have some skills in C++, and/or some kind of CS education, can you really appreciate what Rust is about.

Re:Rust 1.63 by wiseowise on Thursday August 11, 2022 @01:14PM (#32428869)
> Rust tends to favor "mostly functional" architectures over "mutable objet soup" architectures. This pushes you to use less-familiar designs for games and GUI libraries, for example.

How is that a con?

Re:Rust 1.63 by ikawe on Thursday August 11, 2022 @01:34PM (#32429174)
One example would be the lack of pragmatic rust native GUI libraries. There are wrappers for GTK and Qt, which are probably your best option.

The most popular pure rust ones are based on somewhat esoteric patterns and seem prone to being abandoned.

Within that there are some interesting options, like for functionally reactive programming and immediate mode guis, but these paradigms aren’t all encompassing and in fact cover a pretty minority use case based on what GUIs are being created today.

Maybe one day we’ll all only ever create purely functional GUIs and speak Esperanto, but until then, we’re a little hamstrung in rust.

Re:Rust 1.63 by game-of-throws on Thursday August 11, 2022 @01:46PM (#32429335)
I think that's more a function of the newness of the language than anything else. Golang is (I say this as a Rust developer) more popular, has been around longer, yet still has the same dearth of GUI libs.
Re:Rust 1.63 by int_19h on Thursday August 11, 2022 @07:14PM (#32432996)
I can't speak for Go, but idiomatic Rust is not friendly towards the kinds of object graphs that are typical in traditional GUI frameworks with event handlers etc. You either end up with ARC everywhere, which is a pain because it's not transparent in Rust; or you have to come up with the aforementioned "exotic patterns", which significantly raises the bar for adoption.
Re:Rust 1.63 by pkolaczk on Friday August 12, 2022 @02:16AM (#32435191)
Yet, web developers have been using some of those exotic patterns for ages and they don't complain. They even prefer that way to traditional GUIs by using Electron massively now. Rust GUI frameworks are typically based on strict separation between a model and a view and communication between them with messages which is something much closer to web programming than traditional GUI programming. An OOP soup with arbitrary handlers messing around with state directly in random places is IMHO a bad idea in any language anyway.
Re:Rust 1.63 by int_19h on Saturday August 13, 2022 @04:32PM (#32453520)
MVC originated in desktop GUIs, originally for Smalltalk. Java Swing was, I believe, the first mainstream GUI framework which used it thoroughly. Most GUI frameworks since then are also MVC (or some derivative thereof, like MVVM in .NET). This is just a way of organizing code and has little to do with presence of absence of event handlers, or the web.
Re:Rust 1.63 by pkolaczk on Wednesday August 17, 2022 @08:31AM (#32495382)
I didn't mean MVC so much, as message passing between the view and the model. Safe Rust has no problem with MVC nor its derivatives.
Re:Rust 1.63 by oconnor663 on Thursday August 11, 2022 @04:48PM (#32431525)
It's a big piece of the learning curve, and one that usually only shows up when you try to write larger programs. Plus there's very little the compiler can do to point you in the right direction when your object soup needs major refactoring. From what I've seen, a lot of folks either give up on Rust or start writing blatantly unsound unsafe code when they hit this.

On the upside, a lot of C++ game programming uses an ECS-style architecture, which does work well in Rust.

Re:Rust 1.63 by iopq on Thursday August 11, 2022 @06:57PM (#32432857)
When I tried to be more functional, it was really awkward in Rust

I wanted to write some helper functions that applied an argument to a closure and I got this code

    fn apply<A, B, C, G>(mut f: impl FnMut(B) -> G, a: A) -> impl FnMut(&B) -> C
    // must still be `for<'r> impl FnMut(&'r B) -> C`, because that’s what filter requires
    where
    G: FnMut(A) -> C,
    B: Copy, // for dereferencing
    A: Clone,
    {
        move |b| f(*b)(a.clone()) // this must do any bridging necessary to satisfy the requirements
    }
needless to say, Rust doesn't do automatic currying or any advanced functional language tricks so it's just painful to write the same type of code
Re:Rust 1.63 by ekidd on Thursday August 11, 2022 @09:02PM (#32433706)
Yeah, your functional programming skills will probably be most useful at the achitectural level in Rust. Because mutation is very local in Rust, your individual functions can often get away with being imperative, but your overall architecture can't really rely on unrestrained mutation.

But if we zoom in from the architecture to the individual lines of code, Rust is more of a mix of functional and imperative styles. Rust's iterators can be fairly pleasant for working with lazy streams. Closures are more of a mixed bag. This is partly because closures need to worry about ownership, which complicates things by splitting closures up into Fn, FnOnce and FnMut. And each closure is a separate anonymous type. So, yeah, Rust supports quite a few useful things with closures. But as your example shows, the type declarations can quickly become intolerable.

So my strategy is to go with the flow, and keep things simple. I only bring out the heavy type declarations on special occasions, when they provide a big payoff. Otherwise I keep things as simple and boring and concrete as I can.

There are a few popular Rust libraries which make very heavy use of generics. I find that this sometimes backfires, making those libraries slower to compile and harder for me to understand.

Re:Rust 1.63 by albrewer on Friday August 12, 2022 @01:21PM (#32441475)
> I've built a fair amount of production software in Rust.

Any examples?

Re:Rust 1.63 by CJefferson on Thursday August 11, 2022 @12:42PM (#32428383)
Personally, I use Rust as a "better C++".

Ways in which it is better:

* A decent package manager

* "Safe by default" (you have to use 'unsafe' to turn off the safety features), unlike C++ which is "unsafe by default" (v[i] is undefined behaviour if i is out of bounds, for all of C arrays, std::arrays and std::vectors).

* Really easy to do multithreading -- I had reached the point with C and C++ where I was of the opinion it is "almost impossible" to write large thread-safe programs, and all communication should be between processes with pipes, wherever reasonable. In Rust I again feel I can safely and productively write multi-threaded code.

The things Rust doesn't let you do (throw pointers around everywhere) can get a little annoying, but I find the extra safety increases my productivity enough that it's worth the tradeoff.

Re:Rust 1.63 by dralley on Thursday August 11, 2022 @04:03PM (#32431033)
>(you have to use 'unsafe' to turn off the safety features)

"unsafe" doesn't turn off any safety features, it just allows you to do additional things which the base language does not, like:

* use raw pointers

* use mutable static globals

* access fields of unions

https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#unsa...

All the rules of safe Rust still apply inside of unsafe blocks. The borrow checker still works, etc.

Re:Rust 1.63 by tialaramex on Thursday August 11, 2022 @04:17PM (#32431195)
You didn't say otherwise, but this is such a frequent misunderstanding from people who don't write Rust, or write only safe Rust (which is fine) that it's worth pointing out the unsafe keyword and Rust's choice to be "safe by default" are not directly related. Culturally obviously they come from the same place, but for example:

v[i] is bounds checked in Rust even in unsafe. The unsafe "super powers" don't include "magically now indexing has no bounds checks" but because Rust's get function v.get_unchecked(i) is marked unsafe‡ you would need to mark code unsafe to use that function and that function doesn't have bounds checks.

If you write:

  unsafe {
     println!("{}", v[i]);
  }
The compiler will point out that unsafe isn't doing anything for you here, v[i] is safe, marking it unsafe is just a waste of everybody's time.

C++ doesn't have bounds checked array access for its abandoned built-in arrays, but it does (these days) have bounds checked access for std::array and std::vector as a separate member function, however because they aren't the default few C++ programmers use them even where they undoubtedly should. This is an ergonomics issue, it's just easier to write needlessly unsafe C++.

‡ This said just get() before I edited it, but Steve corrected me, see below.

Re:Rust 1.63 by int_19h on Thursday August 11, 2022 @07:17PM (#32433029)
C++ has had std::vector::at() - which checks for out-of-bounds indices - since C++98. The reason why it's not used all that much in practice is because indexing is relatively rare - most of the time, you just iterate over collections, or otherwise use iterators rather than raw indices. And there's no ability to opt into bounds checking for C++ iterators in the standard - implementations usually provide some kind of checked iterators for debug builds, but performance is such that you'd never want that enabled for release.
Re:Rust 1.63 by tialaramex on Friday August 12, 2022 @06:33AM (#32436584)
> indexing is relatively rare

This is also true in Rust for the same reason, arguably more true since Rust's built-in array type knows how big it is - but the observation in both languages programmers who want indexing write v[i] because that's the natural way to express what you meant, what's different isn't the frequency of need, only the language defaults.

> performance is such that you'd never want that enabled for release.

Let's make sure it's correct before we start worrying about performance

https://twitter.com/magdraws/status/1551612747569299458

Re:Rust 1.63 by pjmlp on Friday August 12, 2022 @02:19AM (#32435203)
I always keep them enabled for release, performance is good enough.

Most devs should learn to use profilers.

Re:Rust 1.63 by int_19h on Saturday August 13, 2022 @04:28PM (#32453478)
In what implementation, and what guarantees does its debug iterators provide?
Re:Rust 1.63 by pjmlp on Sunday August 14, 2022 @12:36AM (#32456366)
The one from your employer, Visual C++.
Re:Rust 1.63 by int_19h on Monday August 15, 2022 @04:47AM (#32467292)
If you mean _ITERATOR_DEBUG_LEVEL=1, they're about 4x slower for iteration. I suppose "good enough" is subjective, but if this much is acceptable, I'd rather use C# - it's in the same ballpark.
Re:Rust 1.63 by steveklabnik on Thursday August 11, 2022 @04:42PM (#32431469)
Teeeny tiny note

> because Rust's get function v.get(i) is marked unsafe

You mean get_unchecked. get is safe, and returns an Option, so that None can be returned if something is out of bounds.

Re:Rust 1.63 by tialaramex on Thursday August 11, 2022 @05:22PM (#32431878)
Doh! I even had the "get_unchecked()" function in front of me on the screen and wrote get() anyway. Thanks Steve.
Re:Rust 1.63 by steveklabnik on Thursday August 11, 2022 @05:34PM (#32431997)
No problem. Thanks for explaining what unsafe does and doesn't do; you're 100% right that this is a common misconception that comes up often.
Re:Rust 1.63 by pjmlp on Friday August 12, 2022 @02:18AM (#32435199)
Kind of true, except operator[]() does indeed do bounds checking across all major compilers when compiling in debug mode, and all of them have switches to keep the same behavior in release mode as well.
Re:Rust 1.63 by CJefferson on Thursday August 11, 2022 @05:16PM (#32431805)
You are right, I did know this but it's worth clarifying. Thanks.
Re:Rust 1.63 by kibwen on Thursday August 11, 2022 @12:28PM (#32428146)
I work on a project that's basically a mini-OS designed to host WebAssembly applications.

The OS parts need to run on bare metal and do all sorts of cursed shenanigans, where Rust's separation of safe and unsafe code lets us better focus on proving to ourselves that the unsafe bits are working as intended (we also test our unsafe code under Rust's Miri interpreter/sanitizer for extra confidence). IOW, the killer feature is low-level control plus a reasonable expectation of safety.

The actual WebAssembly interpreter is also written in Rust, which is a good fit because inefficiency in an interpreter leads to inefficiency in anything running in the interpreter. The killer feature here is performance plus safety.

The overall package is bundled up into a CLI app that lets you deploy an instance of our OS with your application running within. Rust has a fairly nice wealth of libraries that make this pleasant, from CLI argument parsers to cryptography to OIDC and beyond. And it all gets packaged up into a single binary for easy distribution (even the OS and interpreter parts, which get embedded directly in the binary via `include_bytes!`). The killer feature here is great platform support (including cross-compilation) and small binaries (though you may reasonably disagree on "small"; altogether the binary (again, including the OS and interpreter) comes out to 25 MB).

Finally, Rust's lack of a pervasive runtime and great WebAssembly tooling means that it's easy to compile Rust applications to run on top of all this as well.

Re:Rust 1.63 by cultureulterior on Thursday August 11, 2022 @12:31PM (#32428194)
This OS seems interesting! Link?
Re:Rust 1.63 by kibwen on Thursday August 11, 2022 @12:40PM (#32428344)
Keep in mind that I'm using "OS" here loosely; it's a bare-metal program that exposes a subset of Linux syscalls so that the interpreter (which itself is compiled for Linux) can run in the extremely specific context that we target. It's still early days so I won't spend too much time shilling it, but all the code is open source and lives under the umbrella of the Linux Foundation: https://enarx.dev/
Re:Rust 1.63 by Macha on Thursday August 11, 2022 @12:16PM (#32427957)
Rust has replaced Python for me in my personal CLI tools where I expect to use them as an ongoing basis. At this stage I am almost as fast writing Rust as Python, find the Rust projects much easier in terms of environment setup than the whole pipenv/poetry/pyenv world, and enjoy the instant response of not having to wait for a python interpreter startup.

I also have some side projects like a gameboy emulator, where it's nice to have what is effectively a lower level language with the safety and features of higher level language.

My day job is mostly Java/Javascript though, rewriting the world isn't yet worth it, but there's certainly one or two of our systems where if a rewrite in another language was on the table I'd make the case for Rust

Re:Rust 1.63 by Scarbutt on Thursday August 11, 2022 @03:58PM (#32430980)
At this stage I am almost as fast writing Rust as Python

By generously use of copying?

Re:Rust 1.63 by oconnor663 on Thursday August 11, 2022 @04:55PM (#32431613)
The "One Simple Trick" that lets you port most Python code straight to Rust is to take all the aliasing "object soup" references that Rust doesn't like, shove those objects in a Vec or a HashMap, and use indexes/keys instead of Rust references. This does require plumbing the Vec/HashMap around through different functions, but if you do it this way from the beginning it's not much extra work.
Re:Rust 1.63 by int_19h on Thursday August 11, 2022 @07:21PM (#32433051)
At that point, what's the benefit of using Rust over basically any other high-level language that has ADTs and pattern matching? Since you lose all the benefits of lifetime tracking that are unique to Rust.
Re:Rust 1.63 by mawfig on Thursday August 11, 2022 @09:26PM (#32433838)
What high-level language with ADTs and pattern matching are you thinking of?

If OCaml, Rust doesn't have weirdly sized number types and has a decent library ecosystem.

If Haskell, you don't need to understand monads to write hello world.

If Scala, you don't need to deploy a JVM with your app.

If F#, you have traits which are super useful and you aren't fighting against MS's refusal to invest in the nicest language in the .Net ecosystem.

Even without "lifetime tracking" and liberal use of Clone, you can still outperform most programs written in any of the above languages.

Re:Rust 1.63 by oconnor663 on Friday August 12, 2022 @07:03PM (#32444991)
> you lose all the benefits of lifetime tracking that are unique to Rust

I think I understand what you're referring to, but stop me if I get this wrong. If you put a bunch of objects in a Vec and refer to them by index, you have to be careful with operations like .insert() and .remove() that shift Vec elements around and change their indexes. Also if you make each element an Option<T> to support deletion without .remove(), you still have to be careful about indexes of deleted objects, because you might put a new object in the same spot later. I have several thoughts about this:

- If "memory safety without garbage collection" is one of the unique features of Rust, you still have that. A reused Vec index in safe Rust code will never corrupt memory or trigger a segfault or anything like that. It's strictly a "logic bug".

- These logic bugs only apply specifically to the objects you put in a Vec and track by index. Creating a Vec<Foo> and getting an index mixed up doesn't change anything about Rust handles your local variable of type Bar (or for that matter, your local variable of type Foo).

- These bugs are understandable for beginners, and you can follow what's going on with print statements. Contrast that with a dangling pointer into a C++ std::vector that just reallocated, where printing the freed object often appears to show good data, and explaining the bug means talking about malloc/new and the heap. Relatedly, unwrapping a None in Rust will always panic and will never coincidentally appear to work. (Your comment was comparing Rust to higher level languages, but I've heard similar comparisons to C++.)

- There are good options for fixing the problem. Beginners might prefer to put their objects in a HashMap with an incrementing key. There's a performance cost to that, but it's familiar and relatively footgun-free. More advanced folks might reach for something like "generational indexes into a slab", which gives you back some performance in exchange for making you learn a bunch of new buzzwords and figure out which implementation to choose from crates.io.

So yes, with those caveats, putting objects into a Vec does turn some compile-time bugs into runtime bugs. That is a downside, much like Rc/Arc/RefCell/Mutex come with runtime downsides. But I've heard folks describe it in terms like "turning off the borrow checker", and I don't think that's a very accurate way of describing it.

Re:Rust 1.63 by int_19h on Saturday August 13, 2022 @04:27PM (#32453471)
As you say, I was specifically comparing to high-level memory-safe languages, not C++. You can't get a dangling reference in Java or C#. Not only that, but you can't get into a situation where some reference points to one object at some point of time, and to another object at a different time - but you can with indices.

The reason why I describe it as "turning off the borrow checker" is because that's exactly what it is - those indices are pointers semantically, but there's no ownership tracking for them. So for them, you turned off the checker. The more you use them, the less checked your code is. If you use this approach in some isolated piece of code, it's one thing. But if it's the go-to solution, then it's reasonable to wonder why you'd do that instead of using a language that has built-in ergonomic safe references with no borrow checking.

Re:Rust 1.63 by oconnor663 on Sunday August 14, 2022 @02:56PM (#32461849)
> but you can with indices

Regular Vec indices yes, but not incrementing HashMap keys or other fancier things, if we set aside overflow issues.

> But if it's the go-to solution

Oh yeah, I should clarify this point. Rust definitely prefers to use simple ownership (i.e. the ownership/reference graph is a tree) wherever possible. As an example, say we've got a Python program with Person objects and Dog objects. Each Person has a `pets` collection that might contain some dogs, and each Dog has an `owner` field that points back to their Person. When we port this program from Python to Rust, Rust isn't going to be happy with the circular relationships between these types, and trying to implement `pets` or `owner` with references probably won't compile.

In cases like this, the most ideal, most idiomatic, go-to option is to break the cycle and try to achieve simple ownership. In this case, that would probably mean making the `pets` collection hold Dogs by value, and removing the `owner` field entirely. Any Dog methods that previously referenced `owner` would need a short-lived reference passed in as an extra argument now, or maybe we could change some of them into Person methods. If we can express our program in this style, that's almost certainly what we want to do.

But there are lots of programs where this doesn't work, at least not everywhere. Maybe a Dog can have multiple owners. Maybe a Dog can have no owner at all. Maybe Dogs want to track their relationships with other Dogs. If people and dogs are independent entities walking around in a game world, or if they represent rows from a couple of tables in some relational database, we probably have lots of problems like this. This is where we start reaching for patterns like Rc<RefCell>/Arc<Mutex> or indexes pointing into Vecs and HashMaps. (I think it's interesting that those Vecs and HashMaps look a lot like db tables.)

A point I want to emphasize here, though, is that even when the most important relationships in our program use these patterns, the majority of our object relationships are probably still simple. If each Person has a `name`, that's still an owned string. If they have an `age`, that's still a regular integer. When our program reads config values from the filesystem, all of our file handles and protocol data still follow simple ownership rules, use destructors for cleanup, and definitely don't get aliased anywhere.

In contrast, if we port our program to Java (or keep it in Python), we can't statically guarantee any simple ownership. Any time we pass a Person or a Dog or a HashMap or a byte buffer to some function, we might worry about that function retaining a reference to it, and we might start making defensive copies or reaching for immutable types. We can still use lots of simple ownership, and for most of our objects we probably do, but we've lost the benefit of a compiler that can check that for us.

Kind of a tangent: When we make aliasing mistakes -- which we can do in Rust in these fancy arrangements, or in Java/Python whenever our data is mutable -- that usually leads to "spooky action at a distance" bugs. Some operation on `foo` has mysterious side effects on `bar`, etc. We've all been there. But I think where these bugs graduate from "annoying" to "insanity-inducing", is when multiple threads get involved. That's when we really want the option of simple, statically-checked ownership, and that's where I think Rust-isms like "Mutex owns the data it protects" are a big improvement over the tools we had before.

Re:Rust 1.63 by kaba0 on Sunday August 14, 2022 @11:12AM (#32459913)
Logic bugs of this sort are way worse (arguably) than some memory corruption errors you might see in C. The latter can be caught by a very manual usage of valgrind and the litany of similar too, while in the former’s case, you have to find that you even have an error, and track it down.

Sure, a beginner may not know about these tools, but my point is about the manuality if fixing the problems, one almost doesn’t need any thinking .

Re:Rust 1.63 by oconnor663 on Sunday August 14, 2022 @01:34PM (#32461156)
I do agree with that point as far as it goes. There are definitely cases (like single-player games) where logic bugs like these suck up more developer time than memory corruption bugs. But I'd push back in a couple ways:

- Much of the time, maybe even most of the time, memory corruption means security vulnerabilities. Logic bugs can be security bugs too, of course, but at least we can reason about them in local terms like "Is this particular part of the program security-sensitive?" Memory corruption doesn't admit the same kind of local reasoning. For any program that touches input from the internet, that's a huge deal.

- Just like C programmers can reach for Valgrind, Rust programmers can reach for design patterns that are more robust than Vec<T>. In this case, HashMap<u64, T> with an incrementing key is a very robust pattern. In practice (until you overflow that u64), that pattern catches 100% of your use-after-free-style mistakes. And I think a major advantage of Rust's approach here compared to Valgrind/ASan, is that it runs in production, so it works even if your test coverage isn't amazing.

Re:Rust 1.63 by ithrow on Thursday August 11, 2022 @07:37PM (#32433155)
You get to be a member of the rust evangelism strikeforce.

Joking aside, I guess devs are lured by the tooling, performance, single binary output and enthusiastic community (more people can see your projects).

Re:Rust 1.63 by __david__ on Thursday August 11, 2022 @04:51PM (#32431569)
For me the killer feature of Rust is its nice broad scope. I've done:

- embedded programs on avr hardware, which is impressive that something like rust can compile down to an 8 bit micro. Doing some sort of crazy map/iterator filter closures and finding the resulting assembly being nice and tight makes me super happy.

- web servers and clients (a scraper that collects scores from a web page and serves its own page of aggregated scores to my family).

- a low level opengl tmux/terminal client (Rust's Enums were a killer feature here)

- a windows GUI program for installing a PC game mod (99% developed on a mac and cross-compiled)

- a cli app to "compile" svgs down to png sprites for a web based game

- a launcher for Emacs that uses native cocoa apis to display a dialog on error

Each of these cases ended up pushing different parts of Rust for me. I would say the killer feature that spans all of those is Cargo and the crates.io registry. There are a ton of very good libraries out there—it feels like the heyday of CPAN or RubyGems to me.

I also quite enjoy how many programming errors Rust finds at compile time. With Rust code I spend way more time fixing compiler errors, but when it compiles I typically don't find a ton of major logic errors. I personally find it extremely rewarding when I get something to compile and then it just works. This happens more in Rust than in other languages I've heavily used.

Re:Rust 1.63 by dymk on Thursday August 11, 2022 @12:42PM (#32428380)
I've written no code professionally in Rust, but a fair amount of personal project code. I've written C++ both professionally and as a hobby. At least for hobby use, comparing the two, Rust is wonderful.

- It's easy to set up cross compilation.

- Cargo makes dependencies easy.

- Building is almost always just `cargo build` except for very exceptional projects, same with `cargo test`.

- `cargo fmt` makes formatting easy and built in.

- Clippy gives actually useful lints and can automate most refactorings.

- Rust-analyzer is fast to index decently large projects, works with almost all language features (even complex ones like proc macros), and has some real time-saver automation built in.

Working with the borrow checker can feel like a pain, but in many cases, feels like a fun puzzle (writing hobby code, I'm not under time pressure, so it's 'solve a puzzle' and not 'oh fuck deadline coming up').

But really, the tooling of the language is where it shines.

Re:Rust 1.63 by shpongled on Thursday August 11, 2022 @12:12PM (#32427883)
I'm building scientific software in Rust.

Phenomenal performance, drop-in concurrency support (`iter()` -> `par_iter()` with Rayon), and a great ML-based type system that makes writing correct code easy.

It also has some of the best developer UX/tooling out of any language I've used.

Re:Rust 1.63 by huyage on Thursday August 11, 2022 @02:24PM (#32429803)
I'm building an HTTP CRUD app on top of PostgreSQL. I have previously used Go for various CRUD apps. The experience is better except for compile time. My favorites:

1. Much more expressive type system: no more `interface{}`.

2. Algebraic data type with `enum`. Exhaustive check.

3. `serde` crate is lightyears ahead of Go's `json:"wtf"`.

4. Compile-time checks against DB with `sqlx` crate.

5. Logging is a breeze with `tracing::instrument`.

6. Using macros to reduce boilerplate has better UX than Go codegen.

What these give me is more confidence in development/refactoring because the compiler can guide me most of the way.

Low lights:

1. Build time.

2. Async is still clunky. e.g. Try to implement an `actix-web` extractor or middleware.

3. Please just stablize nightly rustfmt features already.

Re:Rust 1.63 by mjb8086 on Thursday August 11, 2022 @04:37PM (#32431405)
I'm looking to do a bit of CRUD on top of PostgreSQL as well. Currently mid-way through learning the language.

Would you mind sharing some of your experiences? Do you find the 'stubbornness' of the compiler frustrating at all? How do you find the tooling?

Also, I've considered Diesel for ORM, so was wondering if you've been using that too.

Re:Rust 1.63 by huyage on Thursday August 11, 2022 @05:59PM (#32432282)
> Do you find the 'stubbornness' of the compiler frustrating at all?

I actually love it. The more work I can offload to compiler the better. One simple example that frustrated me in Go was adding a field to a struct. You add the field the the whole thing still compiles even though the zero-initialized value probably broke your app logic. In Rust if I add a field to a struct, the compiler warns me about all the places that I need to double check.

> Would you mind sharing some of your experiences?

I highly recommend zero2prod book which is well-written, practical, but still teaches the essential principles (https://www.zero2prod.com/). You basically deploy a CRUD app to DigitalOcean from scratch. The best way to ramp up IMHO.

> How do you find the tooling?

Cargo is sweet. rust-analyzer is all I need. I need less extraneous tooling to be effective. For example, in Go I might use a task runner to watch the repo and run tests when I change a file. But in Rust I can just follow the rust-analyzer highlights and manually compile less-frequently.

> Also, I've considered Diesel for ORM, so was wondering if you've been using that too.

I was not happy with GORM (https://gorm.io/index.html) and never had a satisfactory experience with any ORM. I'm a fan of writing plain SQL, even in Go. It's just that with Rust sqlx I can get compile-time checks against the schema. It's not anything new (see Haskell), but it tightens the feedback loop and I have full control of the performance.

Re:Rust 1.63 by mjb8086 on Friday August 12, 2022 @04:39AM (#32435935)
Thanks for getting back. I'll take a look at those resources you recommended. Certainly, working with Rust, a lot just 'feels right', it brings together elements I liked from other programming languages like Perl, Erlang, C. Those being: expressiveness, efficiency, a reasonably sane standard library, and functional goodies like immutability and closures.

> You add the field the the whole thing still compiles even though the zero-initialized value probably broke your app logic.

Ah, I found Python notorious for the same reason.

I've found ASP.Net's ORM to be quite good, though this is only with a year's experience, so perhaps I'm missing some cracks that might emerge later.

Re:Rust 1.63 by rizzaxc on Friday August 12, 2022 @05:49AM (#32436326)
do you have experience with protobuf in rust? that's the main thing making me think twice about using rust in backend (protobuf doesn't have an one-true rust library)
Re:Rust 1.63 by bsnnkv on Thursday August 11, 2022 @04:02PM (#32431020)
I've built the most popular[1] actively maintained tiling window manager for Windows that is available today.[2]

It would have been impossible for me to build this in any other language. I knew absolutely 0 about developing for Windows when I started this, but I quickly realized that the Win32 API is a very old beast with a lot of footguns that Rust saves me from on a daily basis.

On top of that, with parking_lot I can quickly and easily detect incredibly rare instances of deadlocks, and in general have to worry very little about concurrency. All of this allows me to stop worrying about the noise and focus on the real work of how the window manager should behave.

1. Based on Github Stars

2. https://github.com/LGUG2Z/komorebi

Re:Rust 1.63 by pornel on Thursday August 11, 2022 @12:12PM (#32427888)
Cloudflare is using Rust for network stacks, proxies, caches, compression, and image processing. Basically everything that you would use C or C++ for, but where security is also incredibly important.
Re:Rust 1.63 by di4na on Thursday August 11, 2022 @01:03PM (#32428703)
NIFs for particular casting of numbers to other binary formats in erlang. NIFS for embedded database and data format in erlang.

Main reason ? It works. The compiler has real error messages that are helpful making the onboarding of anyone having to fix problems a far far better situation than any of the competitors. It has a proper modern toolchain.

All of these would be killer features. All together ? No competition.

I also write cli tool and all kind of parsers for embedded language. The libraries here, in particular if you want good error messages and UX, are simply the best in all other environment i know of.

Re:Rust 1.63 by kylebarron on Thursday August 11, 2022 @12:33PM (#32428224)
I'm building WebAssembly bindings to existing Rust libraries [0] and lower-dependency geospatial tools [1]. Rust makes it very easy to bind rust code to both WebAssembly and Python. And by avoiding some large C geospatial dependencies we can get reliable performance in both wasm and Python using the exact same codebase.

[0]: https://github.com/kylebarron/parquet-wasm

[1]: https://github.com/kylebarron/geopolars

Re:Rust 1.63 by theptip on Thursday August 11, 2022 @01:40PM (#32429244)
Oh, that’s really cool. Rust noob here, and I hadn't seen the tooling for building Python bindings. That looks like it could be a very powerful way to speed up your Python programs (much easier than the “just replace the slow bits in C” advice that was standard.)

The mappings in https://github.com/kylebarron/geopolars/blob/master/py-geopo... for example look very easy to follow.

Re:Rust 1.63 by emadda on Thursday August 11, 2022 @03:25PM (#32430546)
https://table.dog (a CLI to download Stripe to SQLite).

I considered Node.js, C#.

I went with Rust for a few reasons:

- Easy to build small portable binaries (as a primary language feature).

- The type checker ensures type consistency when writing out to SQL tables (SQLite is loosely typed). Code that reads from the SQLite database implicitly benefits from Rusts strong type checks.

- Macros to convert structs to SQL insert/updates.

- Reduce the chance of errors at runtime.

- Leverage as much as SQLite's write throughput as possible.

- When converting Stripes Open API JSON spec into Rust code (using another Node.js program), the Rust type checker ensures I have a well formed HTTP client - the strict compiler makes it a good target for generated programs. Read more about this idea at (https://willcrichton.net/notes/rust-the-new-llvm/).

Re:Rust 1.63 by masklinn on Friday August 12, 2022 @04:40AM (#32435943)
> SQLite is loosely typed

FWIW in recent SQLite you can turn that off using “STRICT” tables, however that means the available types are restricted to INT(EGER), REAL, TEXT, BLOB, or ANY.

ANY is also “Stricter” in strict tables: it does no conversion whatsoever, whereas in normal mode it’ll try to parse literals to numbers, and store a number in that case.

Re:Rust 1.63 by ostenning on Thursday August 11, 2022 @12:25PM (#32428085)
I'm building commercial hardware products using embedded Rust, I love it. I cant really imagine going back to C. I haven't dug too deep into the offerings with this update, but none of the standard library stuff is relevant for me
Re:Rust 1.63 by api on Thursday August 11, 2022 @01:08PM (#32428781)
ZeroTier version 2 is being built in Rust, with the main reasons being safety (it's a network protocol!), easier cross platform compilation, easier dependency management, and an all around better language than C++. It should help us greatly boost developer velocity while also be much safer from a security point of view.
Re:Rust 1.63 by mwcampbell on Thursday August 11, 2022 @02:28PM (#32429841)
That will also make it more attractive to other developers using Rust who want to embed the SDK. Speaking of which, I've emailed ZeroTier a couple of times now about licensing the SDK (the first email was last week), and haven't yet heard back.
Re:Rust 1.63 by cliffcrosland on Thursday August 11, 2022 @12:28PM (#32428147)
We are using Rust to build a fast log event database. The workload includes a lot of asynchronous networking I/O and parallelized CPU-intensive work, like indexing and SIMD-accelerated string search. There are great libraries for what we need. The performance and low memory footprint are quite useful.
Re:Rust 1.63 by andrew_shay on Thursday August 11, 2022 @08:56PM (#32433673)
I've built a p2p file transfer program [0]. All my development experience had been in Python, but I really wanted to try a statically typed, low level language, and decided to give rust a try.

It was hard to get going, and I still only know basics, but everything just works! Typing, borrow checker, the matched results, all of that makes code bullet proof.

[0] https://github.com/transmitic/transmitic

Re:Rust 1.63 by jackmott42 on Thursday August 11, 2022 @12:14PM (#32427921)
I've done some hobby projects in Rust. One was a SIMD abstraction library, where you could write code that looks more or less like SIMD intrinsics, but it would either at compile time or runtime select the SIMD instruction set for the target cpu.

The traits/generics/macro system made that feasible, though messy. You can do similar things with templates in C++

Re:Rust 1.63 by Hamuko on Thursday August 11, 2022 @12:29PM (#32428158)
I've written a small automatic file organiser in Rust that I run in a Docker container on my NAS. Docker reports that the container is using 1.5 MiB of memory, so that's pretty nice. Pretty sure I wouldn't have achieved that if I wrote it in Python like I normally do.
Re:Rust 1.63 by pdimitar on Friday August 12, 2022 @03:26AM (#32435531)
That project sounds interesting and I think it aligns with what I need. Have you open-sourced it?
Re:Rust 1.63 by Hamuko on Friday August 12, 2022 @10:03AM (#32438826)
Nope. I've been meaning to, but I feel like I need to clean up the code up a bit before I do that.

It's also quite niche, so I'm not sure if it's for everyone's use cases.

Re:Rust 1.63 by orthecreedence on Thursday August 11, 2022 @12:20PM (#32428012)
I do a lot of cryptography stuff in rust that is ported to various platforms and embedded in larger apps so I don't have to write the same logic over and over (desktop/mobile mainly).

Also, lately working on some identity/p2p stuff.

Re:Rust 1.63 by mathstuf on Friday August 12, 2022 @10:37AM (#32439337)
I've used it to build two "bulletproof" services that are never intended to go down (the first catches webhook events and puts them to disk and should never go down; the second processes the on-disk files separately so that reloading the configuration can't cause us to miss webhook events). It is far nicer to have error handling as a visible part of the workflow so that you don't get "whoops, didn't consider that" situations (we had this constantly in the Python predecessor that had problems with "uh, you forgot to mention this might not be pure-ASCII, so I'm going to fall over now" problems as various fields popped up with Unicode over time).

Best parts IMO (not in any order and not exhaustive):

- Not having to consider exceptions (panics are still there, but are much closer to the "exceptional" behavior exceptions are/were meant to convey)

- Explicit error handling with (usually) good error types/representation (instead of the nebulous "`err` that is a string" I've seen in what little Golang I've done)

- Threading without worrying about race conditions

- Dependency management

- Data structure focused (instead of object focused)

- The built-in `#[test]` features are also great and make it easy to test internal code without exposing it in some strange way purely for testing purposes.

FWIW, I find that it also makes your C++ far better because now you can more easily "see" lifetime problems that people tend to write out of habit (`return stackstr.c_str();` is a…favorite that compilers now warn about).

Re:Rust 1.63 by solar-ice on Thursday August 11, 2022 @01:22PM (#32428993)
I write video streaming software in Rust. Rust helps us make sure we've got concurrency correct, has a very solid type system to help us make sure we've got general application properties correct, and seriously reduces the space where we have to go looking for segfaults and suchlike (primarily third-party C libraries and bindings to them).
Re:Rust 1.63 by marcosdumay on Thursday August 11, 2022 @04:32PM (#32431350)
I am currently writing a kinda complex GUI application intended to run on a browser. So it's in webassembly.

Compared to Javascript, Rust safety features allow me to iterate quickly and improves my productivity from "I won't be able to complete this project" to "it's trivial, just some work". Compared to Typescript, Rust gives me some performance and types that actually represent the data I use, but I am not sure if I lost a bit of productivity (the TS tooling is horrible, so programing a bit slower isn't the entire story).

I don't consider this a problem Rust is good for, but one that all the more suitable languages still don't support.

Re:Rust 1.63 by gattr on Thursday August 11, 2022 @12:54PM (#32428588)
I wrote a video acquisition tool for astrophotography [1] (and I dogfood it). Uses GTK3 for GUI.

[1] https://github.com/GreatAttractor/vidoxide

Re:Rust 1.63 by allisdust on Thursday August 11, 2022 @01:04PM (#32428713)
I use it to write backend web services. Some how it doesn't appear to be any less productive than typescript +nodejs combination. Library support used to be a mess but now a lot of good libraries exist to get the job done.
Re:Rust 1.63 by pjmlp on Thursday August 11, 2022 @02:27PM (#32429834)
Only hobby coding.

Java, .NET languages and C++ are what pay the bills for me.

Re:Rust 1.63 by teknopurge on Thursday August 11, 2022 @12:31PM (#32428190)
security. I dabble with system programs and it's nice to get the speed/portability of native optimized code and know most memory issues won't occur.
Re:Rust 1.63 by nynx on Thursday August 11, 2022 @12:12PM (#32427887)
I’ve written a bunch of embedded software in rust.