Live data from Hacker News

Safety: A comparaison between Rust, C++ and Go

nested.substack.com

11–20 of 188 posts

Re: Safety: A comparaison between Rust, C++ and Go

#11
Disingenuous.

The bad C++ code is in the very first line of the "make_appender" definition: capturing the closure's environment by reference is nonsense: It is equivalent to returning a reference to an argument. It is not, then, a closure at all.

Using a correctly-defined make_appender would not, then, produce undefined behavior when you use it, with or without "move".

What the author has done here was to take a too-obviously wrong operation, returning a reference to an argument, but dress it up with syntax that will look less familiar to some readers, and pass it off as insightful.

But using a wrong function and getting wrong results is not surprising.

Piling on more uses after, that give more wrong results, does not reveal anything more.

When you need disingenuous arguments to make your point, it tells us more about your point than about the thing you are trying to make a point about. And, publishing anyway tells us more about you.

Returning that fake closure should evoke a compiler warning, if you turn on warnings.

Re: Safety: A comparaison between Rust, C++ and Go

#12
post #5

Java falls a bit in between Go and Rust on that example: Closures only allow variables that are effectively final, aka you can’t reassign them (the compiler will stop you). But you could pass an object and update its internal state.

"final" in Java is kind of useless, really. A const mechanism like C++ has would go a long way and would be a perfect fit for the OO nature of the language.

Re: Safety: A comparaison between Rust, C++ and Go

#14
post #9
post #4

Earlier quoted context omitted.

Your point is a fair one, but defaults matter. There's little reason for clang-tidy not to be part of the default clang invocation by now, other than an aversion to producing new output for existing projects (that you could argue are already "broken"). Unless clang-tidy has false positives, in which case the comparison isn't apples to apples then.

> Unless clang-tidy has false positives, in which case the comparison isn't apples to apples then. Confused... so you're suggesting Rust's checks are somehow free of false positives? Doesn't the halting problem get in the way? One Rust-specific example: https://www.reddit.com/r/rust/comments/nr7a33/is_the_borrow_...

There's a difference between code that used to compile no longer compiling because of an incorrect lint, and code that was never accepted. Rust is restrictive and gets less so over time. C and C++ need to become more restrictive over time, but that's a more traumatic direction.

Re: Safety: A comparaison between Rust, C++ and Go

#15
post #9
post #4

Earlier quoted context omitted.

Your point is a fair one, but defaults matter. There's little reason for clang-tidy not to be part of the default clang invocation by now, other than an aversion to producing new output for existing projects (that you could argue are already "broken"). Unless clang-tidy has false positives, in which case the comparison isn't apples to apples then.

> Unless clang-tidy has false positives, in which case the comparison isn't apples to apples then. Confused... so you're suggesting Rust's checks are somehow free of false positives? Doesn't the halting problem get in the way? One Rust-specific example: https://www.reddit.com/r/rust/comments/nr7a33/is_the_borrow_...

I find it so weird that the Rust community is borderline evangelical about memory safety when a) it's not actually memory safe once you start doing heavy shit b) modern C++ is quite memory safe and c) there are so many other great reasons to like Rust.

Memory safety in serious systems software is something that you approach asymptotically and/or probabilistically. Rust makes it easier to be memory safe in a lot of scenarios, at the cost of the father-knows-best borrow checker, but a crashed program is a crashed program whether I dereferenced a null pointer or was poking around in a slice with multi-byte Unicode characters in it. And that's before you get to `rg unsafe` on your favorite industrial-strength Rust codebase.

Rust is cool for so many great reasons that get talked about so little because everyone seems too busy acting superior about memory safety. Talk about traits! Or Cargo! Or the cool async stuff! Anything but another lecture on memory safety.

Re: Safety: A comparaison between Rust, C++ and Go

#16
post #11

Disingenuous. The bad C++ code is in the very first line of the "make_appender" definition: capturing the closure's environment by reference is nonsense: It is equivalent to returning a reference to an argument. It is not, then, a closure at all. Using a correctly-defined make_appender would not, then, produce undefined behavior when you use it, with or without "move". What the author has done here was to take a too-…

[deleted]

Re: Safety: A comparaison between Rust, C++ and Go

#17
post #4

Earlier quoted context omitted.

Your point is a fair one, but defaults matter. There's little reason for clang-tidy not to be part of the default clang invocation by now, other than an aversion to producing new output for existing projects (that you could argue are already "broken"). Unless clang-tidy has false positives, in which case the comparison isn't apples to apples then.

Oh I completely agree that defaults matter, and I wouldn't advise anyone to go start some big C++ project unless they had a very good reason to. But Rust vs. C++ is not an apples-to-apples comparison in this regard: Rust got a clean slate and was willing to cut ties with engineer-millenia of existing high-value software to do it. In a perfect world Rust wouldn't be ambivalent at best and hostile at worst to C++ inter…

Rust isn't hostile about C++ interop, it's that between native interop (which requires dealing with templates and memory unsafety) and safety, Rust prioritized safety, while Carbon is trying the alternate approach. The behavior of C++ is simply hard to interface with while providing the assurances Rust gives you.

Edit: how many languages have native C++ interop that supports the whole language? Would love to hear of any.

Re: Safety: A comparaison between Rust, C++ and Go

#18
post #11

Disingenuous. The bad C++ code is in the very first line of the "make_appender" definition: capturing the closure's environment by reference is nonsense: It is equivalent to returning a reference to an argument. It is not, then, a closure at all. Using a correctly-defined make_appender would not, then, produce undefined behavior when you use it, with or without "move". What the author has done here was to take a too-…

I was trying to be a little more diplomatic in my sibling reply because I've locked horns with the Rust community before and not enjoyed it, but you're not wrong.

Re: Safety: A comparaison between Rust, C++ and Go

#19

Earlier quoted context omitted.

Oh I completely agree that defaults matter, and I wouldn't advise anyone to go start some big C++ project unless they had a very good reason to. But Rust vs. C++ is not an apples-to-apples comparison in this regard: Rust got a clean slate and was willing to cut ties with engineer-millenia of existing high-value software to do it. In a perfect world Rust wouldn't be ambivalent at best and hostile at worst to C++ inter…

Rust isn't hostile about C++ interop, it's that between native interop (which requires dealing with templates and memory unsafety) and safety, Rust prioritized safety, while Carbon is trying the alternate approach. The behavior of C++ is simply hard to interface with while providing the assurances Rust gives you. Edit: how many languages have native C++ interop that supports the whole language? Would love to hear of…

I said ambivalent to hostile at worst, and I'm sorry, it is. I write FFI to C++ in Rust, Python, and Haskell practically every week, and Rust C++ sucks.

Slap it in an `unsafe` block, fine. But let me move a `std::vector` into my `unsafe` block easily. Erase the types, fine. But let me call `v.at(idx)`.

Python takes C++ interop seriously, which is why Tensorflow and PyTorch and all the other people trying to script gigantic, extreme-value C++ codebases use it. Try `pybind11` sometime, it's night and day.

Edit to reply to edit: `pybind11` supports an absurd amount of C++ out of the box with completely natural semantics and a very modest performance penalty. So, Python.

Re: Safety: A comparaison between Rust, C++ and Go

#20
post #9

Earlier quoted context omitted.

> Unless clang-tidy has false positives, in which case the comparison isn't apples to apples then. Confused... so you're suggesting Rust's checks are somehow free of false positives? Doesn't the halting problem get in the way? One Rust-specific example: https://www.reddit.com/r/rust/comments/nr7a33/is_the_borrow_...

There's a difference between code that used to compile no longer compiling because of an incorrect lint, and code that was never accepted. Rust is restrictive and gets less so over time. C and C++ need to become more restrictive over time, but that's a more traumatic direction.

What you're actually arguing seems to be "why I like Rust more than C++", not arguing why "clang-tidy has false positives, and thus the comparison isn't apples to apples then".

Clearly the positives can be just as false in Rust as in C++. Your actual objection is that anyone arguing that any feature of Clang can measure up to the corresponding feature of Rust at present is automatically disqualified from making that argument because... Clang's past "taints" its present? Like an original sin of sorts, but in programming? ("Apple" forbidden against comparison?)

Post reply on HN