News for hackers. Stuff that matters.
Re:Rust Weird Expressions by larschdk on Friday May 14, 2021 @11:19AM (#27155195)
I often feel the same, and there is certainly a bit of learning curve, but in my experience, all the time you spend battling the compiler in Rust is time saved from debugging in C++, several times over. I'm repeatedly surprised by how my code just works when it finally compiles. It's like the compiler is telling you, "you just made a bug".
Re:Rust Weird Expressions by skohan on Friday May 14, 2021 @11:42AM (#27155437)
Just to give an alternate viewpoint, I'm currently writing most of my code in Rust, and while I am generally a fan of the language, and a huge fan of the tooling and community, I think Rust often gets a pass on complexity because it's mostly compared against C++ which is itself a monstrosity. There are many, many other languages to which Rust seems insanely complex and difficult to program in by comparison. I think that often gets blamed on accommodating the borrow checker, and Rust's low-level nature, but I think a lot of it is avoidable.
Re:Rust Weird Expressions by steveklabnik on Friday May 14, 2021 @11:48AM (#27155518)
I'm curious, not saying you're right or wrong: what bits do you think are avoidable?

Personally, I agree that Rust is complex, but almost all of that complexity is inherent to the kinds of tradeoffs Rust makes. With different tradeoffs, I can certainly imagine a much simpler language, but it's less clear to me what stuff could be significantly simplified without doing so. However, I am extremely biased!

Re:Rust Weird Expressions by skohan on Friday May 14, 2021 @12:24PM (#27156043)
My go-to example would be the module system:

1. 90% of the time, rust module layouts are basically a copy of the file-system heirarchy, so why do I have to type this? This system would be much more approachable if it gave the file-system hierarchy as the default module layout, and let you override it explicitly. The argument I have heard against this is that some people like to comment out module declarations during debugging. I don't find this compelling, because I don't see why you couldn't have an explicit way to ignore a module instead. This is just one of many cases where Rust seems to prioritize the edge case at the expense of the common case.

2. On top of requiring a lot of boilerplate the module system is quite esoteric. I've had to learn it twice: a few years ago I was dabbling in Rust, and I remember having to struggle a bit to understand how to add a second file to my project, and then about a year ago when I was getting back into rust I found it unintuitive a second time. I challenge you to find someone who is unfamiliar with the module system, and see how long it takes them, using only the documentation, to figure out where they have to put the `mod` declarations to add nested submodules to their project to make it compile. Maybe I am unreasonably thick, but I don't think it's my problem since I've worked with a lot of languages, and never had this much trouble.

3. This esoteric system isn't even deterministic. Imagine I have the line `mod foo` in my `lib.rs`. Where can I go to find the source for that? Well, it depends. It could be in `src/foo.rs`, or it could be in `src/foo/mod.rs`. And let's say I'm using external crate: `use some_crate`. Which import does that correspond to? It could be: `some_crate`, or it could be `some-crate` in my `Cargo.toml`. You just have to kind of know all of these implicit behaviors of the compiler to know what's going on.

So this is just one feature, but IMO it's just one example of a case where Rust puts very little emphasis on the UX and understandability of the language.

Re:Rust Weird Expressions by steveklabnik on Friday May 14, 2021 @12:29PM (#27156126)
Cool thanks! This is a great example of my mental bias, actually: I don't tend to think of the module system as a "language feature" even though it clearly is!

There are some good reasons and interesting arguments around all this, but given that I was just curious about your opinion, I won't bore you with all that :) Thanks!

Re:Rust Weird Expressions by skohan on Friday May 14, 2021 @12:40PM (#27156287)
No worries, happy to share!
Re:Rust Weird Expressions by iudqnolq on Friday May 14, 2021 @12:27PM (#27156092)
I definitely think you're right that the module system is complicated, even the new module system. I would like to make one nit though: it's definitely deterministic. Deterministic just means it can be predicted, not that you specifically can predict it. If the module system was non-deterministic that would be a much bigger issue
Re:Rust Weird Expressions by skohan on Friday May 14, 2021 @12:33PM (#27156192)
Ok fair enough, that is true. I guess it would be more accurate to say that a module declaration is ambiguous with respect to the file-system location of the code it's referring to.
Re:Rust Weird Expressions by skoodge on Friday May 14, 2021 @12:27PM (#27156084)
I'll chime in and say that for me at least, the module system was a hurdle at the start and coincidentally the only part of the language where the explanation in The Book (which is excellent, so thank you, btw!) did not click for me.

I think it's debatable whether the module system really is complex or just different from what newcomers are used to (and by now I've grown pretty accustomed to it). But in contrast to most other language features, where it was clear what I was getting in return for the steep learning curve, the module system seemed overly complicated at the time for no real benefit. Not a big issue by any means and I would choose Rust with its module system over the alternatives most days of the week, but it is one tradeoff that to me at least seemed orthogonal to the other borrowing-related complexities.

(What is more worrying to me nowadays is the whole async story. I do hope that some of it will get better once certain features land and it is certainly an area where some additional complexity is unavoidable, but it is the only part of Rust that I dread touching despite heavily using async in a moderately sized personal project due to the need for WASM + IndexedDB, simply because lifetime issues become much more tricky once async and either traits, recursion or closures are involved. By now I am consciously trying to limit any async parts of the program to a simple and stupid "Rust-light" style without any "fancy" features such as traits or closures, which does not feel like a proper solution. So yeah, in general I agree with you: Rust is certainly complex, but for the most part not unnecessarily so.)

Re:Rust Weird Expressions by steveklabnik on Friday May 14, 2021 @12:53PM (#27156500)
Thanks!

Yeah, teaching the module system is kind of my white whale. Carol and I have spent more time on that part of the book than almost any other; re-written like five times.

My current working theory is that most people assume that "the module system" is similar to whatever one they've used in the past, then run into problems, and leads to frustration. I've talked to so many people who have totally opposite problems with it, with no real pattern to issues or expectations.

I think that it's very straightforward, personally, with very very simple rules (especially in 2018). But I certainly acknowledge that I am the exception, not the rule.

Re:Rust Weird Expressions by orthoxerox on Friday May 14, 2021 @05:02PM (#27159652)
> My current working theory is that most people assume that "the module system" is similar to whatever one they've used in the past, then run into problems, and leads to frustration. I've talked to so many people who have totally opposite problems with it, with no real pattern to issues or expectations.

When I treated modules as Java packages or C# namespaces I hated them. Only when I realized that I can treat them as glorified C imports did they start to make sense. I still hate them, but at least I can rationalize their design now.

Re:Rust Weird Expressions by rabidferret on Friday May 14, 2021 @01:19PM (#27156901)
> I think that it's very straightforward, personally, with very very simple rules (especially in 2018).

I agree with you. It's a shame we don't have a simple visual metaphor to describe this

EDIT: Wait does hacker news just delete non-ascii? I tried to put an upside down smiley here how is this even worse than I thought

Re:Rust Weird Expressions by steveklabnik on Friday May 14, 2021 @01:33PM (#27157128)
https://news.ycombinator.com/formatdoc is the only actual description, but it does seem that non-ascii text is ignored, yes.
Re:Rust Weird Expressions by saagarjha on Friday May 14, 2021 @06:38PM (#27160420)
The rules are mainly there to filter out emoji; it can do most non-ASCII outside of that. L͇̭̝̲͍̠̼͒̌̋̄͟͝ͅi̢̭̬̥͍̣͓͗͆͆̄͝k̸̙̹̠̘̤̪͓̼̠̋̽̿̇̕͜͝͠ė̜͙̥̟͍͇͉͖͌́̑̈́̎͐ Ž̶̨̛͇͙̹͖̳̂͊͐̅̇̓a̸̭͙͇͙͙̝̟̯̮̠͌̊̑̏͊͡ĺ̸̻̟̩̼̙͈̒̿̀̈̓̌́̐̓ģ̵͉̺̹̥̤͎̟̓̓̑̋̈́̇͢͜͡ơ̷͖̤͎̮͈͆̌̿͂̂̚͘.̴̱̬̮̟͖͆̄̉̔̏͛̒̇̌ͅ
Re:Rust Weird Expressions by rabidferret on Saturday May 15, 2021 @08:00AM (#27164441)
Why would they filter emoji specifically? They're such a major part of modern communication
Re:Rust Weird Expressions by mlindner on Saturday May 15, 2021 @05:16PM (#27169103)
I don't know what "modern communication" you're using, but the only emoji I use are ones that can be written in simple ascii, :( , :-/ , :) , :D , ;) , etc. Most emoji are simply symbols for different activities, but they don't need to be used at all. The only place I see heavy use of emoji is on twitter, but that's because of the character limitation. Additionally emoji are colored and not black and white like text so they're glaring with respect to text around them.
Re:Rust Weird Expressions by saagarjha on Saturday May 15, 2021 @03:09PM (#27167973)
My guess is that they draw undue attention to themselves.
Re:Rust Weird Expressions by estebank on Friday May 14, 2021 @12:38PM (#27156274)
You might be interested in taking a look at and potentially participating in the "Async Vision Document"[1] which is an exercise the team is going through to collect feedback about the current state of the ecosystem and what the pain points are, as well as a way to lay doing what the desired future state of async Rust should be[2]. The process is happening, as you would expect, in the open and there's still time to influence it[3] if your concerns aren't yet addressed or even mentioned[4].

[1]: https://rust-lang.github.io/wg-async-foundations/vision.html

[2]: https://blog.rust-lang.org/2021/03/18/async-vision-doc.html

[3]: https://github.com/rust-lang/wg-async-foundations/pulls

[4]: https://github.com/rust-lang/wg-async-foundations/issues

Re:Rust Weird Expressions by bsder on Friday May 14, 2021 @05:27PM (#27159887)
> By now I am consciously trying to limit any async parts of the program to a simple and stupid "Rust-light" style without any "fancy" features such as traits or closures, which does not feel like a proper solution.

I disagree that this is bad, and I think you've made a good decision.

I find that too many Rust programmers reach for a closure WAY too often and, even when they should grab a closure, they make it far too complicated. Closures should be short. Inline closures are nice when they're a single line part of "collect()" (although, I've seen some that make me want to hang the author ...).

However, if your closure is 15 lines long invoking a builder chain (this is a common issue in EventLoop type closures), that should be a function. This is before I get started about how builder chains are a gigantic misfeature to paper over the fact that the language doesn't have default/named function arguments.

Anyway ... I have found that "make it a named function and call it" is often a far better way to communicate exactly what your intent was.

Re:Rust Weird Expressions by skohan on Friday May 14, 2021 @05:58PM (#27160133)
> builder chains are a gigantic misfeature to paper over the fact that the language doesn't have default/named function arguments.

Totally agree. I think it's telling that Rust Analyzer basically inserts argument labels inline in the editor, and this is the preferred way to work with Rust.

Re:Rust Weird Expressions by torrent on Tuesday May 18, 2021 @04:50PM (#27200895)
After your battle with the compiler is over and it compiles it does not mean your program is correct! If you now what you you have no issues with C++. It's not the language. It's the design, approach and attitude
Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @11:54AM (#27155604)
If you ever find yourself spending time "debugging in C++", you are Doing It Wrong. Coding modern C++ right is the same, that way, as coding Rust: when it compiles, it works.

(In general, if you find yourself inventing falsehoods about other languages to promote Rust, you are Doing That Wrong, too.)

I have personally spent more time, summed over the past decade, preparing bug reports against Gcc than in debugging C++ memory-usage faults.

But C++ compiles faster.

Coding Rust is fun in much the way that Forth is: it is a charge to figure out a way to achieve a thing; you know it will ultimately be possible, and when you find the way, it is an ego boost. You could say, "Rust is the Second Programming Religion", and who could ever honestly disagree?

(But watch extremists downvote this to oblivion anyway.)

Re:Rust Weird Expressions by kortex on Friday May 14, 2021 @03:26PM (#27158666)
> Coding modern C++ right is the same, that way, as coding Rust: when it compiles, it works.

Works in what way? Serious question. Do you mean "works" as in 1) "doesn't crash/seg/overflow" or 2) "doesn't UB" or 3) "doesn't have race bugs" or 4) "does what the programmer intended"?

I would say from my experience, none are strictly true. I'll hazard you mean to imply the dev knows the language pretty well in order to satisfy "works lvl 1" but you still have veterans running into bugs of the 2-4 variety.

But even to get to (1), C++ requires a ton of domain knowledge. I've been working with C++ intensively for several months and incidentally for years, and I still seg every now and then. Even after using Valgrind, it feels rickety. Meanwhile, I've spent a few dozen weekends on Rust and I just feel way more confidence that my program will "just work" without crashing.

That's all still "level 1 works". When it comes to race conditions and programmer intent making its way into correct code, it's no comparison. Rust is way easier to get my intent into a running program. C++, I still have to lean into logs and debugging, because it just doesn't quite do what I want a non-trivial amount of the time.

It's not a religion. Rust simply is a better experience. I can say that having learned both basically side-by-side.

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @10:04PM (#27161635)
Works as (4), does what I intended.

It takes discipline to learn to write C++ in the modern way. It is work to keep up with improvements in the language and library, as new Standards are published. But many, many professionals do. C++ is not a toy. It has sharp edges that must be treated with respect. But if you do make the effort to keep up, and lean hard on the type system to help everywhere it can, the language delivers.

If your code feels rickety, it is. You have at hand the tools to fix that. If you find yourself coding races, it is because you have not adopted means to prevent them.

I can testify that coding in modern C++ can be pure fun. I never have occasion to worry about memory safety, or data races. Code not working the way (I thought) I wanted, on first run, is very much the exception.

Re:Rust Weird Expressions by shakow on Friday May 14, 2021 @10:26PM (#27161748)
> It takes discipline to learn to write C++ in the modern way. It is work to keep up with improvements in the language and library, as new Standards are published. But many, many professionals do. C++ is not a toy. It has sharp edges that must be treated with respect. But if you do make the effort to keep up, and lean hard on the type system to help everywhere it can, the language delivers.

If it is such a core just to hope to, one day, be able to code that, maybe, won't crash, what do you think is the point of using C++ over Rust?

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @10:52PM (#27161879)
C++ doesn't need a point. C++ is a mature language with mature tooling, an installed base of tens or hundreds of billions of lines of code, millions of professionals worldwide getting critical work done every day, with guaranteed prospects decades into the future. You personally depend on C++ code not crashing hundreds or thousands of times every day, without knowing it.

In some possible futures, Rust code may take up just a bit of the load. The most value would come from its displacing C and Java in new projects.

Re:Rust Weird Expressions by kaslai on Saturday May 15, 2021 @01:43AM (#27162750)
I depend on a mountain of C and C++ code to not only not crash, but to also not have any subtle memory errors which might allow a packet from the internet to run arbitrary code on my machines. Failures of that sort are disturbingly common.
Re:Rust Weird Expressions by ncmncm on Saturday May 15, 2021 @02:09AM (#27162851)
You stand to gain more by people modernizing their existing code -- even, compiling their C code with a C++ compiler, and then improving that, as happened with excellent results in gcc and gdb -- than by hoping a vanishing few will switch over to a wholly new, unfamiliar language.

Liiterally millions of times more benefit.

Re:Rust Weird Expressions by emtel on Friday May 14, 2021 @02:28PM (#27157944)
The only way this is even close to true, imo, is you have really good tests and have taken the time to get those tests running with every available sanitizer, including MemorySanitizer (which is a huge pain).

And even then, I think you're still behind rust. Sanitizers can only catch data races / memory errors / uninitialized reads / etc that actually happen. OTOH, Rust _proves_ that your program doesn't have these faults (modulo unsafe blocks).

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @03:05PM (#27158427)
If you are relying on testing for correctness, you have already lost. In any language.

As Dijkstra noted, testing can only prove a program wrong. The way to get correct programs, in any expressive-enough language, is by construction. At each level, do only operations that are well-defined by the level below. Expose only well-defined operations to the next level up. The compiler proves that the types are used correctly; so, when coding a library, you put the type system to work to make wrong code harder than correct code.

That is the right way to code Rust, too.

Re:Rust Weird Expressions by oalae5niMiel7qu on Tuesday May 18, 2021 @05:45PM (#27201648)
Dijkstra once explained what he meant when he claimed you could "derive" correct programs mathematically:

https://www.cs.utexas.edu/users/EWD/ewd11xx/EWD1162.PDF

In this paper, he begins with a program written in what I believe to be propositional logic notation. This program can't be typed into an HN comment, but it can be trivially translated in to Common Lisp:

(loop for k from 0 below n always (f k))

The rest of the paper is about him translating this program into another kind of math notation with C-like semantics. By the end of the paper, he has proven that the second, lower-level program is equivalent to the first program, which is the same thing that a compiler does.

He does not prove that the thing he originally wrote at the beginning correctly expresses his intentions. So his method is basically this:

1. Write a bug-free program in a very high-level programming language, or a very rigorous pseudocode.

2. Translate it to a low-level language.

3. Prove that the translation is equivalent to the original program.

Re:Rust Weird Expressions by orneryostrich on Saturday May 15, 2021 @12:10AM (#27162282)
You do know that every operating system and CPU in existence has ill-defined operations, right?

The best-defined software I know of is SQLite. Every function is carefully documented with a description of all failure modes and returned error codes.

But also... SQLite has one of the most comprehensive test suites in existence, so I guess they lost? https://www.sqlite.org/testing.html

Re:Rust Weird Expressions by ncmncm on Saturday May 15, 2021 @03:35AM (#27163234)
SQLite is coded in C. Correct-by-construction was not among the choices available.

SQLite are in a good position to switch to building with a C++ compiler, and then modernize incrementally. They won't, for cultural reasons. They probably could use that C-to-Rust translator thing that was used on Quake3, but they won't do that either, for better reasons.

Re:Rust Weird Expressions by orneryostrich on Tuesday May 18, 2021 @04:23PM (#27200526)
C++ is even less well-defined than C, though. We find defects in the standard and inconsistencies between Clang/G++/MSVC every day.

You’re demanding a rigor that is not possible with a modern technology stack.

Re:Rust Weird Expressions by kazinator on Tuesday May 18, 2021 @04:26PM (#27200549)
In a greenfield project, you can restrict the code base to stable C++ dialect (all the way back to C++98 if necessary), and you can dictate the use of C++ features which make it safer than C. For instance, smart pointers for all memory allocation.
Re:Rust Weird Expressions by orneryostrich on Tuesday May 18, 2021 @08:55PM (#27203317)
This isn't really the point I'm responding to.

I am responding to this idea:

> If you are relying on testing for correctness, you have already lost. In any language. As Dijkstra noted, testing can only prove a program wrong. The way to get correct programs, in any expressive-enough language, is by construction. At each level, do only operations that are well-defined by the level below. Expose only well-defined operations to the next level up.

I believe this idea is naïve. CPUs contain undocumented instructions, and they expose implementation details via speculative execution and timing attacks.

So... by this metric, we have already lost.

I think I also take issue with the idea that there is a stable C++ dialect. GCC, Clang, and MSVC have always disagreed on how they interpret the C++ standard.

If you want portable code, there is no substitute for testing your program with every compiler you support and on every architecture you support. Proofs won't save you and the standard won't save you, because both proofs and the standard assume that we started from a bug-free foundation that doesn't actually exist.

Re:Rust Weird Expressions by kazinator on Wednesday May 19, 2021 @10:45AM (#27209366)
If you use undocumented instructions, you're not following "do only operations that are well-defined by the level below". The existence of undocumented instructions doesn't invalidate the concept of correctness by contract.

You don't seem to realize that testing and proofs are just two faces of the same thing. A test is just an empirical proof of something. Both are rooted in the same logic and assumptions. In fact, in some cases, a test can be exhaustive and then it's as good as a proof. Tests usually have the disadvantage of being inexhaustive, and having to work their logic within the language.

I'm getting to the point that security software, such as an OS kernel, that is vulnerable to timing and speculative execution attacks, is that way not only in spite of being proven, but in spite of testing also.

It's not the case that proofs will fail to reveal that problem, but testing will.

No amount of testing will reveal a problem missed by proof methods, if both the testing and proving are rooted in the same false assumptions.

(Assumptions like "the hardware's protections mechanisms are sound, so that no data flows are observable to an unauthorized domain, so we just have to test the software itself is good.")

Re:Rust Weird Expressions by kazinator on Wednesday May 19, 2021 @05:19PM (#27214600)
Erratum: testing, of course, exercises every layer you depend on, whereas proof methods typically assume that the things below conform to their contracts. That is where proofs are weak. A proof will show that your code is correct; a test will reveal a compiler bug, CPU bug, faulty RAM, ...
Re:Rust Weird Expressions by orneryostrich on Thursday May 20, 2021 @10:12AM (#27221317)
Oh! This erratum is the point I’ve been trying to get across. It sounds like we agree on this?
Re:Rust Weird Expressions by emtel on Sunday May 16, 2021 @10:54AM (#27174123)
Which was my point. Rust proves more about its programs than does C++.
Re:Rust Weird Expressions by skohan on Friday May 14, 2021 @12:29PM (#27156119)
> it is a charge to figure out a way to achieve a thing; you know it will ultimately be possible, and when you find the way, it is an ego boost.

This is actually something I agree with, even as a fan of Rust. Sometimes I wonder to what extent the appeal of Rust is based in the fact that you get to feel like a CS undergrad again, climbing mountains to make code compile and run

Re:Rust Weird Expressions by nix0n on Friday May 14, 2021 @01:44PM (#27157307)
> Coding modern C++ right[...]: when it compiles, it works

I don't believe this, but I'd love to be wrong. Is there an exemplary codebase somewhere that I can take a look at?

Re:Rust Weird Expressions by shakow on Friday May 14, 2021 @01:52PM (#27157414)
I can give you an example I used a few months ago:

    struct Shape {
      Shape() { init(); };

      void init() { reset(); };
      virtual void reset() = 0;
    };

    struct Point: Shape {
      virtual void reset() { _x = _y = 0; }
      double _x, _y;
    };


    int main() {
      Point p; // KA-BOOM
    }
Compiles without any warning with -Wall & -Wpedantic, fails at run.
Re:Rust Weird Expressions by nix0n on Friday May 14, 2021 @02:11PM (#27157699)
You've misunderstood me, "ncmncm" has claimed that a "right" way to code C++ exists. I would like to see such a codebase, if one exists.

Clearly, this isn't it, but I do appreciate the interesting snippet. Would the compiler have caught this if `Shape()` called `reset()` directly?

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @02:56PM (#27158311)
Thank you, this is an example of '90s-style C++, serving as a nice contrast to modern C++. Nowadays we would write

  struct Point {
    double x{}, y{};  // zero-initialization
  };

  int main() {
    Point p;  // ok, {0.0, 0.0}
    ...
    p = Point{}; // no need for a "reset"
  }
It has been literal decades since anyone competent would have made a Point derived with virtuals, or have written so much code to achieve so little. (You might see stuff like that at Google.) You can write bad code in any language, but if you have to do extra work to make bad code, it is not tempting.
Re:Rust Weird Expressions by shakow on Friday May 14, 2021 @03:20PM (#27158590)
> if you have to do extra work

I would argue that (i) old-fashioned code is not deliberately going out of your way to write bad code, and (ii) this should, at the very least, trigger a warning from the compiler.

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @03:35PM (#27158793)
Old-fashioned code is not necessarily bad code, although the example was; but the topic was "modern C++", not "old-fashioned C++".

Anytime you do all the extra work to write old-fashioned code, you have earned the outcome you get. The oldest-fashioned code looks just like C, which you can still write in a C++ program, if you want to. But there is no reasonable temptation to. Good modern code is equally fast, often faster, and more easily written, understood, and maintained.

Re:Rust Weird Expressions by kelnos on Friday May 14, 2021 @06:07PM (#27160211)
I haven't done any serious C++ in about 15 years.

If I were to try to pick it up again today, I would have to learn "modern C++"[0] incrementally. I would still have some old habits, and they would take time to iron out. My guess is that it would take me at least a year, possibly more, to become fully proficient in "modern C++".

And even then, I'd still expect that I'd occasionally write some C++ in the "old" way. Maybe I'm tired and forget, maybe I'm lazy and want a shortcut. Who knows. The compiler won't save me from my "old C++". It'll be there, warts and footguns and all.

I'd much rather write in a language designed to not have these problems in the first place, and let the compiler catch as many problems as it can.

[0] Whatever "modern C++" means; I suspect current C++ developers can reasonably disagree on the details, as has been the case for the entire history of C++.

Re:Rust Weird Expressions by linkdd on Friday May 14, 2021 @06:21PM (#27160309)
Modern C++ is what was in the Boost framework 15 years ago.</troll>

Joke aside, the STL grew in complexity and features to provide more compile-time constructs and to integrate more functional programming aspects.

For example: I've been told many times that in "modern C++" you don't need `new` nor `delete`.

There are smart pointers, std::array, std::optional, const-expressions, you'll find more and more "single-header" libraries (for JSON, an either monad, etc...), even modules[1].

It's like learning a new language. C++11, 14, 17 and 20 are completely different to C++03 while remaining backward compatible (a critical feature for C/C++ languages it seems).

[1] - https://en.cppreference.com/w/cpp/language/modules

Re:Rust Weird Expressions by shakow on Friday May 14, 2021 @03:50PM (#27158949)
> but the topic was "modern C++", not "old-fashioned C++".

The problem being that there is no definition of “modern” C++, and even less so that would be enforced by compilers.

> Anytime you do all the extra work

There is no extra work to write “old-fashioned” code. Quite the opposite actually; one has to indicate to compilers to accept newer features rather than the opposite.

> Good modern code

This is a very flimsy, handy-wavy concept, that changes drastically from one “best practice” guide to the other.

Re:Rust Weird Expressions by ByteJockey on Friday May 14, 2021 @10:18PM (#27161700)
> The problem being that there is no definition of “modern” C++

When people say this, they almost always mean making heavy use of C++11 (and later) features, defaulting to `unique_ptr` (or `shared_ptr` if it absolutely needs to be passed around), etc.

Also there's a sizeable minority of people who also mean staying on the stack whenever possible. Which, don't get me wrong, is a good thing, but that's been a thing going all the way back to C. I chalk that particular one up to those people having to debug C++ code written by java devs.

Re:Rust Weird Expressions by ncmncm on Saturday May 15, 2021 @07:54PM (#27170020)
ByteJockey refers to value types, and value semantics.

Besides value types' benefits to code comprehension, they often give the optimizer enormously more latitude to operate because it knows there are no stray pointers to the object.

Over-use of std::shared_ptr is called Java Disease. It has been seen to be curable. A value object containing just a std::unique_ptr<Impl> member (often called "Pimpl", pointer-to-implementation) gets most benefits of value semantics, in cases where Impl is bigger than you would want to pass around directly, and stylistically is overwhelmingly better than passing and returning std::unique_ptr.

Re:Rust Weird Expressions by linkdd on Friday May 14, 2021 @11:59AM (#27155676)
It was my understanding that the memory model of Rust is inherently different than C++'s.

Genuine noob question: can you really compare Rust's borrow checker and lifetime management to the smart pointers in C++?

Re:Rust Weird Expressions by steveklabnik on Friday May 14, 2021 @12:02PM (#27155731)
You can compare them, but the comparison won't show that they're equal :p

C++'s smart pointers have direct analogues in Rust, though there are some differences. (unique_ptr<T> and Box<T>, shared_ptr<T> and Rc<T>/Arc<T>)

The borrow checker is something else completely. The closest analogue in C++ is the https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines, which offer some similar kinds of checks to Rust, but don't attempt to go nearly as far as Rust does.

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @12:18PM (#27155954)
There is nothing similar between Rust's borrow checker and anything in C++.

In modern C++ you get compile-time correctness by construction: you do things that reduce to correct code. All of the low-level mistakes remain possible, but are not tempting. Low-level, C-like operations are like writing "unsafe" in Rust; you can if you want to, or need to, but they are uglier, and anyway almost always not needed. Just as when coding a Rust "unsafe" block: if it ever is, you use extra care.

In a very real sense, C++ libraries perform in the role of the Rust compiler by insulating you from operations that are risky. The operations a good library exposes are safe. A Rust compiler bug could expose you to a memory fault, in the same way that a C++ library bug could; but the Rust compiler is well exercised and tested, much as is is a mature library. You need libraries anyway.

Re:Rust Weird Expressions by estebank on Friday May 14, 2021 @12:49PM (#27156439)
Genuine question, is iterator invalidation still a problem that people can hit with modern C++ constructs? A quick search seems to answer "yes"[1], but I'm not involved in writing C++ to evaluate what the common mitigations are.

For what is worth, I believe that 99% of what you can express in one language you can in the other. If you're hitting walls with the borrow checker when writing Rust you always have the options of either using the equivalents of unique_ptr<T> and shared_ptr<T>, or of cloning memory.

> A Rust compiler bug could expose you to a memory fault, in the same way that a C++ library bug could; but the compiler is well exercised and tested, much as is is a mature library.

I'm not sure what this sentence was expressing, but it seems you're implying here that rustc isn't well exercised and tested?

[1]: https://medium.com/@lightcone/iterator-invalidation-in-moder...

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @01:01PM (#27156595)
Iterator invalidation, like pointer invalidation, remains a thing. Iterators and pointers are normally treated as ephemeral, except where guarantees are provided.

It is hard for me to imagine how "the compiler is well exercised and tested" could be perceived to mean the opposite. Explain?

Re:Rust Weird Expressions by estebank on Friday May 14, 2021 @01:25PM (#27157026)
> It is hard for me to imagine how "the compiler is well exercised and tested" could be perceived to mean the opposite. Explain?

I misread it as talking about modern c++ compilers and libraries being well exercised and tested, and contrasting that with rustc.

Re:Rust Weird Expressions by galangalalgol on Friday May 14, 2021 @03:34PM (#27158787)
Thats fine until "that guy" grabs the raw pointer out of a smart pointer and deletes it, or c style casts an interface to his version of the interface because he wanted it to return an int instead of a double. Then either pushes straight to dev or rounds up similarly evil individuals to approve the merge. I have debugged those errors. You can talk about accountability but even if you manage to get rid of one such dev there always seem to be more. And modern C++ doesn't really have great tools for thread safety. Its easier to get right than in 98, but still not hard to get wrong.
Re:Rust Weird Expressions by kelnos on Friday May 14, 2021 @06:21PM (#27160304)
I think you're fundamentally misunderstanding the objections people have to "modern C++" when compared to Rust.

You say that it's not "tempting" to use less-safe constructs in C++ these days, but that's not the point. You are assuming a perfect C++ developer who never makes mistakes and always knows to use the proper, modern constructs, and will properly document any time that they absolutely must use a less-safe construct, and that documentation will never drift or go out of date.

That developer does not exist in any meaningful or useful way. Developers make mistakes. Developers don't always have completely up-to-date knowledge or understanding of what the correct, "modern C++" way is to do literally everything. A developer who genuinely does need to do something less safe may or may not document it, and anyone who comes by later and changes the code may not update the documentation accordingly.

The Rust compiler will not allow you to do unsafe things (absent bugs in rustc); attempting to do so is a compiler error. If you really must do unsafe things, you must surround that code in an unsafe block, which serves as documentation that must be kept up to date, or the code will not compile. Others can inspect your code and very easily decide if they want to use it based on how much unsafe code they are willing to accept.

I don't want a compiler that will only ensure certain kinds of correctness if I already know how to write things in the "correct way" (which has traditionally been a moving target in the C++ world). I want a compiler that will ensure those types of correctness always, and reject programs where it can't give me that guarantee. The C++ compiler will not do that, but the Rust compiler will.

> In modern C++ you get compile-time correctness by construction

No you don't! You only get this if you've written your code correctly! The entire point of "correct by construction, verified by the compiler" is that you cannot write the code in an incorrect way that the compiler will accept. And the C++ compiler absolutely will accept "old-school C++" that could be incorrect. Put another way, there is no C++ compiler that will only accept "modern C++" and reject "old-school C++". And even if someone were to try to write such a thing (I am skeptical it's possible), reasonable, knowledgeable C++ developers could easily disagree on what should and shouldn't be included.

Re:Rust Weird Expressions by ncmncm on Friday May 14, 2021 @09:24PM (#27161427)
> Developers make mistakes. Developers don't always have completely up-to-date knowledge...

Fair enough. Yet, there are literally many thousands of fully competent, up to date C++ developers for each person who ever so much as compiled a hello.rs. (Probably the majority of the latter are among the former.) By 2030, under the absolute best-case scenario for Rust, there will still be literally millions of times as much C++ code as Rust code to maintain and improve upon.

> The Rust compiler will not allow you to do unsafe things ...[without] an unsafe block ...

In other words, the Rust compiler will allow you to do unsafe things with the addition of 8 characters. The temptation to that varies.

> The entire point of "correct by construction[...]" is that you cannot write the code in an incorrect way

The C++ language provides a comprehensive type system that enables the compiler, with well-engineered libraries, to prove correct use of types the libraries define. This depends on library designers taking up the mantle that the Rust compiler takes for itself. As they do.

But you need competently constructed libraries anyway, in Rust as much as in C++. Many demands are placed on library designers and implementers. Ensuring that only correct usage compiles (absent "unsafe") is not among the most difficult of those demands.

Rust will not save the world. That would be asking too much of it. There is no substitute for competence. Rust is not one.

C++ improves on a strict three-year cycle, and new C++ code can be demonstrably better, by any measure, than was possible for old code. To the degree that Rust and modern C++ can displace C, Java, and bad old C++ code, both can contribute to a better future world. Rust will not displace C++ in any plausible future, but not displacing C++ will not mean Rust has failed.