Live data from Hacker News

Switching from C++ to Rust

laplab.me

241–250 of 289 posts

Re: Switching from C++ to Rust

#241

The author mentioned that Rust errors sometimes force you to restructure your code to satisfy the borrow checker. I’m curious whether anyone has some real-world before-and-after examples of this kind of change.

The most common example is when you accidentally start doing object-orientation, and are trying to get a value to hold a reference to another value when there's no point in doing so from an ownership perspective, just so that it can be part of `self` in the method. The more you try to preserve the model, the wackier the errors get, until one of them is literally unsolvable and you have to junk the object-oriented des…

I come from OOP languages and do rust mostly nowadays.

> you have to junk the object-oriented design entirely

I think it's not this black-and-white. OOP on a higher level is about encapsulation and message passing. Such design is perfectly doable in Rust. I'd say that it's more natural in Rust due to it's `impl` concept: where behaviour and data are coupled in a way that's different from most OOP languages.

Who owns which data, and who can operate on it, is something that, in OOP, should be thought about just as well. Java, Ruby, et al make it easy to make a mess from this; yet that doesn't make all OO-design a mess. Ihat really is "bad use of OOP", and no reason to "junk the OO design entirely". At most it's "junk the bad OO design".

Re: Switching from C++ to Rust

#242
post #183

Earlier quoted context omitted.

An important distinction is that rust doesn’t use exceptions for recoverable errors. You don’t have try/catch like you do in C++. Instead you use the Result type to propagate errors. This has the advantage of avoiding many of the downsides of exceptions (like leaving your program in a bad state) while making error handling more explicit.

Rust programmers misuse unwrap and the like all the time, to the point that I’ve seen some projects explicitly state that they don’t do that, since nobody wants their library to crash their program because someone was too lazy to propagate errors. Which brings me to the point: propagating errors is tedious enough that people are looking for shortcuts, which then cause other problems.

For other folks following along and possibly getting mislead by this (partial) nonsense, I'd encourage you to read a blog post I wrote about the topic of unwrap. I think it should clear up most things: https://blog.burntsushi.net/unwrap/

At a meta level, one of the reasons why there is so much focus on 'unwrap()' in particular is because it is often the precise point at which in your code where a runtime invariant is broken and thus leads to a panic. Nearly all code has runtime invariants in one form or another. The question is what happens when they're broken. In languages that are memory unsafe by default, the answer is often (but not always) "undefined behavior." In languages like Rust, or Python, or Go, the answer is often (but not always) "the process quits." The reality is more complicated than that, but those are a fine first approximation. For example, breaking a runtime invariant doesn't have to lead to undefined behavior or process termination. It can simply result in a logic error that leads to unexpected behavior.

Of course, making the issue more complicated is that sometimes 'unwrap()' is abused. And indeed, sometimes it is used in cases where an error ought to be returned. I find this to be generally pretty rare in popular libraries. But the key point here is that you can't just say, "oh I see unwrap() in a library, so now I'm going to scream ABUSE!!!!" It's more complicated than that.

Re: Switching from C++ to Rust

#243
post #171

Earlier quoted context omitted.

Variant types where one has to use objects as types don’t come up that often in API design or data structures in my experience with mobile and system programming on e.g. Linux. I think I’ve genuinely had to use them only a few times. Error types are probably the most popular incarnation of that. There’s several libraries available and they will be part of the C++ standard. This is a case of the Rust community oversel…

> Variant types where one has to use objects as types don’t come up that often in API design or data structures in my experience with mobile and system programming on e.g. Linux You can't use what you don't have, so you adapt to the tools you do have. In my C++ time, the team would often write types that logically held several variants. However they were expressed as product types, so with space overhead and error-pr…

not to diminish value of sum types (those are not specific to Rust of course) but I think that product types belong to a database / config rather than being hardcoded.

Re: Switching from C++ to Rust

#244

Earlier quoted context omitted.

I'm not certain for C, but definitely in C++ it's legal to union a bunch of structures with a common prefix, and then talk about the prefix in the "wrong" variant and that's OK. There may be some restrictions about exactly what is in that prefix, but at least obvious things like an enum or an integral type will work. So for your example you put ShapeType type in each of Rectangle, Circle, Triangle etc. and then you c…

> I'm not certain for C, but definitely in C++ it's legal to union a bunch of structures with a common prefix, and then talk about the prefix in the "wrong" variant and that's OK That doesn't sound right to me. Do you have a source? Is that in the standard?

I of course do not own a copy of the expensive ISO document, however, in the draft:

11.5.1 [class.union.general]

[Note 1: One special guarantee is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout structs that share a common initial sequence ([class.mem]), and if a non-static data member of an object of this standard-layout union type is active and is one of the standard-layout structs, it is permitted to inspect the common initial sequence of any of the standard-layout struct members; see [class.mem]. — end note]

Re: Switching from C++ to Rust

#245

The call out to sum types is something I feel. I've been using Rust daily for almost 10 years now, and sum types are absolutely still one of the things I love most about it. It's easily one of the things I miss the most in other languages that don't have them. I'm usually a proponent of "using languages as they're intended," but I missed exhaustiveness checking so much that I ported a version of it to Go[1] as a sort…

A nice thing about Rust is that it brings many well established good ideas from the ML branch of languages to the curly brave branch of languages. And frankly does a better job naming them (for people who weren’t math majors).

Completely agree. This article [0] by Raphael Poss, explicitly listing how functional constructs look in Rust compared with "pure" functional languages is one of my favorite takes on Rust.

[0]: https://dr-knz.net/rust-for-functional-programmers.html

Re: Switching from C++ to Rust

#246

Earlier quoted context omitted.

So, so many ways in which this is defective compared to actual sum types, some of them were already listed, but to me the most crucial, even if mostly about theory rather than practice, is valueless_by_exception. The choice to provide exceptions everywhere as a error handling means C++ is obliged to admit that your std::variant may not have a value at all. Which blows up all of your type safety. In Rust I can say tha…

Exceptions are an optional feature. Also, if sufficient amount of constructors are marked noexcept, then the variant can never be valueless. Implementations are optimized accordingly. You also don't have to handle the exception, in which case you won't access the variant again anyway. Or it gets handled where the variant is teared down. It's very unlikely that it gets handled where the variant is constructed or assig…

They aren't as per ISO C++, even though all compilers allow to disable them in non standard conforming ways.

Re: Switching from C++ to Rust

#247

Earlier quoted context omitted.

Problem is, unless it has been tried in court, you can't be certain. And if you're building something, you might not want to spend time in court having to fight it in the first place. So even if it's 50/50 enforceable/not enforceable, do you really want to spend the time testing if it is? Patents really have a chilling effect, even if a particular one might not be enforceable.

Also the ISO is also very averse of patents. They will probably not standardize anything patent-encumbered. They would probably require invalidating the patent first before accepting it in the standard. Having said that this is the first time I ever heard of methods on enums being patented, what a ridiculous patent. It's a good thing then that C++ doesn't have methods, it has "member functions" :). Also C++ allows us…

WG21 (the "C++ Committee") is under JTC1 the Joint Technical Committee ("joint" between ISO and IEC), now, you might know of a few other famous products of the Joint Technical Committee's sub and sub-sub committees, including JPEG (that's the Joint Photographic Experts Group getting a shout out in the name of the standard) and MPEG. Those standards both required patented "inventions" to implement in full. The patents were held by contributors...

In the case of MPEG the result is MPEG LA, a US company which you need to pay to implement certain important standards. In the case of JPEG the result was a little different, since only the improved Arithmetic Coding of JPEG was patented, people just don't implement the actual standard, they cut out the patented part, so all the world's JPEGs (well, mostly JFIF files, which are slightly different but we call them "JPEGs" anyway) are a little bigger than they need to be for no reason except patents.

So no, I don't buy that "ISO is also very averse of patents" in a sense that would restrict this unless you can show that's a new stance.

Re: Switching from C++ to Rust

#248
post #236

Earlier quoted context omitted.

You forgot to add /s. Thanks but no, replacing a bunch of code as strings and then relying on some code _not_ compiling should be left in 20th century for good.

I have a feeling you're talking about C macros, not C++ templates.

SFINAE

Re: Switching from C++ to Rust

#249

Earlier quoted context omitted.

What libraries have you found to use unwrap liberally?

The standard library is one example. Indexing into a vector unwraps, as do many other stdlib functions.

> Indexing into a vector unwraps

That's what it's supposed to do, RTFM.

Use .get() for safe access.

Re: Switching from C++ to Rust

#250
post #225

Earlier quoted context omitted.

I don't know what the issue is but I've tried esp-wifi on the ESP32-C3 with the examples and nothing would run. It's a bummer since I'd have liked to leverage the Bluetooth support for my project.

Esp-wifi is very actively being updated, looks like C3 is supposed to work[0][1], so if you tried more than a few weeks ago it probably changed. [0]: https://github.com/esp-rs/esp-wifi#current-support [1]: https://github.com/esp-rs/esp-wifi#ble

Thanks for mentioning it. I already tried using it a few months ago and brushed it off as still being a WIP, but it still didn't work when I tried again just a few days ago. Asking in the Matrix chat when first trying it sadly only got me a "works for me" from the developers.

What Espressif is doing with their esp-idf and porting it to Rust is promising, but overall it still needs work. Using the toolchain to develop on the ESP32 was at least slightly painful half a year ago before they introduced espup[1], having to keep a patched LLVM around etc., and supposedly support for their Xtensa architecture is coming to LLVM soon[2] so this will improve in the future.

I'd also love to see Bluetooth support in esp-idf-svc[3], but they seem to be lacking people with the required knowledge to design and implement an abstraction for it[4].

[1]: https://github.com/esp-rs/espup [2]: https://mabez.dev/blog/posts/esp-rust-24-02-2023/ [3]: https://github.com/esp-rs/esp-idf-svc [4]: https://github.com/esp-rs/esp-idf-svc/issues/55#issuecomment...

Post reply on HN