Live data from Hacker News

C++ to Rust Phrasebook

cel.cs.brown.edu

31–40 of 80 posts

Re: C++ to Rust Phrasebook

#31

One of the common pitfalls I've seen in my time is someone writing a language they are familiar with in a language that just doesn't fit; trying to apply idioms that flow well with one language to another language where that's just not a good way to achieve the same ends. An example I've seen a lot is a C thinker writing C++ classes with an init() function; sure, it works, but the C++ way is to do that in constructor…

The rationale is probably that it’s better for C++ devs to write non idiomatic Rust than to keep writing unsafe C++. Like unless they use unsafe and completely circumvent the borrow checker, it’s still gonna be safer. Not letting perfect be the enemy of good and all.

Plus idiomatic rust isn’t that strict a definition. Clippy will guide you for most of the simple stuff and the rest isn’t always worth following. Like people who try to do stuff “correctly” with traits often end up with way more complexity than it’s worth.

Re: C++ to Rust Phrasebook

#32
post #12

One of the common pitfalls I've seen in my time is someone writing a language they are familiar with in a language that just doesn't fit; trying to apply idioms that flow well with one language to another language where that's just not a good way to achieve the same ends. An example I've seen a lot is a C thinker writing C++ classes with an init() function; sure, it works, but the C++ way is to do that in constructor…

To be fair, there's a reason for the pattern with init methods you're describing. C++ constructors can't return values. If construction is fallible, the only way to communicate the error is via C++ exceptions. If you're in a code base that embraces exceptions, that's fine. But (C++) exceptions kind of suck, so many code bases don't, and then you have to find some alternatives. Over the years, I've increasingly adopte…

> the object construction can be done with static methods

I've done that a lot too, but I found that free functions are much better for this than static member functions, because you can't get CTAD from static member functions. For example, with constructors we could write:

  vector{1, 2, 3}; // deduces vector
And with a static member, we would need:

  vector::init(1, 2, 3);
With a free function, we could write:

  make_vector(1, 2, 3); // returns vector

Re: C++ to Rust Phrasebook

#33
post #23

Earlier quoted context omitted.

How would you deal with fallible construction of objects while avoiding exceptions in idiomatic C++?

This was one of the best decisions that Rust and Go did; not have constructors. In C# this is super annoying too, specially when you need an async operation to construct a type. This is usually done by having an private constructor and then using a static public method to create the type.

Rust and Go have no form of a conversion operator (even if not a constructor), which makes scripting a type system essentially impossible. Numeric libraries in both of those languages are extremely cumbersome, largely for this reason.

Re: C++ to Rust Phrasebook

#34
post #8

Earlier quoted context omitted.

I've taken a look, and it's definitely expecting you to know some C++. Or at least, it spends equal time on both, which means it can't warn you about the foot guns in c++.

It's definitely written from the perspective of someone who "knows C++". But I put that in quotes because there are (at least) two interpretations of that phrase. There's the person who doesn't know any C++ at all, and for that person, this is useless. But there's the person who knows a baseline of C++ but doesn't know modern C++, and they can use this as a way to modernize their C++ code while ignoring the Rust bits…

There are patterns diffused in this paper that are modern C++ only in the sense that anything post C++11 is modern C++. That was 14 years ago, you will be hard pressed to find a toolchain that doesn’t support C++17 at this point, yes there is probably some unfortunate person building for debian old-stable or some ancient but still supported redhat but at that point you know you aren’t following modern practices and you have your reasons.

Re: C++ to Rust Phrasebook

#36
post #19
post #12

Earlier quoted context omitted.

To be fair, there's a reason for the pattern with init methods you're describing. C++ constructors can't return values. If construction is fallible, the only way to communicate the error is via C++ exceptions. If you're in a code base that embraces exceptions, that's fine. But (C++) exceptions kind of suck, so many code bases don't, and then you have to find some alternatives. Over the years, I've increasingly adopte…

Two-phase initialization also has the added benefit of usually making the object have a constexpr constructor (usually a default constructor) and therefore making it eligible for constinit. That said, construct_at also exists.

Nothing prevents std::vector from having a `constexpr` default-constructor except that it's not considered useful to do if you cannot follow that up with initializing its data in a constant context. For instance, this isn't very useful:

  constinit vector v;
But this would be more so:

  constinit vector v(16, 1); // Fill with 16 1's.
And the reason we can't do this wouldn't be solved by splitting it into multiple functions.

EDIT: Actually, come to think of it, C++20's vector already supports the first example. It's just not used much that way because it's not very helpful.

https://godbolt.org/z/avY4M9oMK

Re: C++ to Rust Phrasebook

#37
post #28
post #27

Earlier quoted context omitted.

C++ syntax and semantics are optimized for C++ idioms, and Rust's aren't. Rust is more related to ML-family languages than C-family and OOP, so it needs to "emulate" some C++ idioms. This goes both ways, e.g. equivalent of Rust's pattern matching on enums with data translates to verbose and clunky C++.

So you are saying that this approach teaches C++ users to use the wrong idioms in Rust?

Wrong is too strong. The code is okay given the constraint — this is a guide for C++ programmers thinking in C++ terms, not for teaching purely idiomatic Rust from the ground up.

Re: C++ to Rust Phrasebook

#38
post #15

Earlier quoted context omitted.

Visual Studio and Clion are the ones currently with the best experience regarding modules. And in VS could be much better, but EDG has other priorities. VSCode isn't really that great option for C/C++.

I prefer vscode simply because VS is excruciatingly slow. e.g. the file open pane in vscode pretty much instantly lists the file I'm looking for, while the counterpart in VS (ctrl+,) takes several seconds and intermixes search results for files and file contents, when I'm only interested in files.

Same here, those "mini" delays are not worth.

Re: C++ to Rust Phrasebook

#39
post #15

Earlier quoted context omitted.

Visual Studio and Clion are the ones currently with the best experience regarding modules. And in VS could be much better, but EDG has other priorities. VSCode isn't really that great option for C/C++.

I prefer vscode simply because VS is excruciatingly slow. e.g. the file open pane in vscode pretty much instantly lists the file I'm looking for, while the counterpart in VS (ctrl+,) takes several seconds and intermixes search results for files and file contents, when I'm only interested in files.

Ctrl+, followed by f filename, you will get the file.

The only reasons I use VSCode are the plugins I cannot get on VS, like Powershell, Rust, Azure tooling, and for stuff like Next.js, better use an editor that is anyway a browser in disguise.

Performance has never been a part of my decision flowchart.

Re: C++ to Rust Phrasebook

#40
post #23

Earlier quoted context omitted.

To be fair, there's a reason for the pattern with init methods you're describing. Without prejudice on any other reasons, the most common reason for this pattern I've seen is people thinking in languages that basically don't have constructors, yet writing C++. It's not a good reason.

How would you deal with fallible construction of objects while avoiding exceptions in idiomatic C++?

Idiomatic C++ uses exceptions.

The standard doesn't allow to disable language features.

Anyone that goes into the dark side of disabling language features is writing unidiomatic C++ with compiler specific extensions.

Post reply on HN