News for hackers. Stuff that matters.
Re:Comparing Parallel Rust and C++ by kbumsik on Thursday November 07, 2019 @05:32AM (#21472003)
Maybe because I'm not familiar with Rust, but I always have kind of impressions that Rust code is very hard to read. It is just impossible to figure out what the code is doing for beginners.

[C++ code]: https://github.com/parallel-rust-cpp/shortcut-comparison/blo...

[Rust code]: https://github.com/parallel-rust-cpp/shortcut-comparison/blo...

Re:Comparing Parallel Rust and C++ by edflsafoiewq on Thursday November 07, 2019 @07:01AM (#21472388)
The Rust is practically line noise. This is just awful

    let pack_simd_row = |(i, (vd_stripe, vt_stripe)): (usize, (&mut [f32x8], &mut [f32x8]))| {
        for (jv, (vx, vy)) in vd_stripe.iter_mut().zip(vt_stripe.iter_mut()).enumerate() {
            let mut vx_tmp = [std::f32::INFINITY; simd::f32x8_LENGTH];
            let mut vy_tmp = [std::f32::INFINITY; simd::f32x8_LENGTH];
            for (b, (x, y)) in vx_tmp.iter_mut().zip(vy_tmp.iter_mut()).enumerate() {
And I tend to write stuff like this in Rust too. The loops especially. It's just so easy to throw together all those iterator combinators and get some ugly blob that's going to make people's eyes glaze over.
Re:Comparing Parallel Rust and C++ by cogman10 on Thursday November 07, 2019 @12:18PM (#21475073)
I honestly don't see what's so bad about this. About the only thing that might be more useful is better variable names and maybe a function or two to clear up exactly what's going on. But even still, this is math heavy code. I don't think I've ever seen math heavy code (particularly dealing with matrix manipulation) that didn't end up looking like this.
Re:Comparing Parallel Rust and C++ by brutt on Thursday November 07, 2019 @12:45PM (#21475359)
Code is easy to follow. I see no problem there.

`pack_simd_row` is lambda: `|arguments: types| { body }` Arguments are: * `i` of type `usize` (unisgned size_t), * tuple (anonymous struct) with two fields: vd_stripe and vt_stripe, which are modified inside of lambda. They are references to fixed size array of 8 floats.

Inside function we have loop over result of iterator, which produces tuple with two fields: `jv` and tuple with two fields: `vx` and `vy`. `vx` and `vy` are elements from `vd_stripe` and `vt_stripe`. `jv` is their index.

Inside loop we create two temporary mutable variables: `vx_tmp` and `vy_tmp`, which are fixed size array of 8 floats, which are initialized with infinity.

Then we have next loop, which goes to modify these temporary arrays in place.

And so on.

Re:Comparing Parallel Rust and C++ by jml7c5 on Thursday November 07, 2019 @02:21PM (#21476377)
While the Rust version does flow logically, succinctness helps a lot more than people seem to appreciate. It's one of the reasons math notation is often so inconsistent: the brevity allows for easier manipulation and scanning. (Though I would not stretch the analogy too far, as inconsistent and overy brief notation can limit understanding while reading proofs.)

Being able to fit part of a program clearly into 5 lines with fewer characters makes it easier to ensure correctness than an algorithm spread over 10 lines that is full of extra "noise". It's why there's so much syntactic sugar in so many languages.

Re:Comparing Parallel Rust and C++ by tluyben2 on Friday November 08, 2019 @11:25AM (#21483724)
It is easy to follow but I cannot say it's very pleasing to read.
Re:Comparing Parallel Rust and C++ by snaky on Thursday November 07, 2019 @11:18AM (#21474522)
Maybe it's time to propose alternative syntax for Rust?
Re:Comparing Parallel Rust and C++ by rezeroed on Thursday November 07, 2019 @02:21PM (#21476379)
I could produce greater horror with c# linq.
Re:Comparing Parallel Rust and C++ by tluyben2 on Friday November 08, 2019 @11:24AM (#21483711)
Please give us an example. I have read a lot of linq; it never looked quite this horrible so I am curious.
Re:Comparing Parallel Rust and C++ by exDM69 on Thursday November 07, 2019 @05:56AM (#21472125)
The reason the C++ code looks simple is that it uses OpenMP #pragma parallel for, which is a very easy way of doing very simple loop parallelization.

By contrast the Rust example uses parallel iterators from the Rayon crate. If the C++ example had something similar using a C++ library, it would probably be worse.

It's not Rust vs. C++, it's OpenMP directives vs. explicitly writing multithreaded code.

Re:Comparing Parallel Rust and C++ by gpderetta on Thursday November 07, 2019 @07:28AM (#21472561)
Well, the whole purpose of OpenMP is to be a syntactically lightweight way of parallelizing code; it is a well supported standard. C++17 in fact has paralel extensions to the standard library, but if you have access to OpenMP it is often better.

OpenMP is not C++ specific, it is also supported in fortran and C (although the newer OpenMP standards have first class support for C++ iterator semantics). In principle it could also be supported in rust although I assume that making it work with the borrow checker might not be easy.

Re:Comparing Parallel Rust and C++ by blub on Thursday November 07, 2019 @06:15AM (#21472199)
The calls starting with par_ are by far not the biggest readability problem. The Rust code has a lot of noise, whereas the C++ reads like almost like a straight C implementation that anyone could understand.
Re:Comparing Parallel Rust and C++ by exDM69 on Thursday November 07, 2019 @06:55AM (#21472349)
Would you like to point out specific instances of this "noise"?

The C++ code looks like straightforward "C code" because it's using the OpenMP parallel for. If it dealt with threads explicitly it would not look as pretty.

I do agree that the Rust code has some verbosity, for example there are a lot of type annotations and using named constants instead of magic values.

For example (C++):

    int na = (n + 8 - 1) / 8;
Versus (you could write this like the above too):

    let vecs_per_col = (n + simd::f32x8_LENGTH - 1) / simd::f32x8_LENGTH;
An example of the type annotations (are they really necessary?):

    let pack_simd_row = |(i, (vd_stripe, vt_stripe)): (usize, (&mut [f32x8], &mut [f32x8]))| {
Comparing the actual internals of the algorithm is quite straightforward, e.g. look at the middle loop (lines 70-82 in Rust vs. 58-97 in C++). Do note that the C++ code is loop unrolled by hand which makes it look simpler.

In the Rust code, there's a pretty cool feature where multithreading can be toggled on/off with a compile time flag, see parts with: #[cfg(not(feature = "no-multi-thread"))]

If the C++ example wouldn't use OpenMP, this would be pretty impossible to achieve without being noisy too.

Also note that even with OpenMP, it would be quite easy to create a memory unsafety issue in the C++ code by for example accessing an array out of bounds inside the loop body.

Apart from these, I have no problems reading and understanding the C++ or Rust code (and I'm a noob with Rust).

Re:Comparing Parallel Rust and C++ by imtringued on Thursday November 07, 2019 @06:57PM (#21478750)
From what I have read Rust users don't seem to care about OpenMP at all. Some even go as far to say that they would prefer using something like a Rayon alternative for C++ instead.
Re:Comparing Parallel Rust and C++ by exDM69 on Friday November 08, 2019 @07:57AM (#21481779)
It's not obvious how the hypothetical OpenMP for Rust should work. If you'd put #pragma omp parallel for in front of a loop, there would be no compile time guarantees of memory safety or freedom from data races.

OpenMP is suitable for the most simplest kind of parallelism in the first place.

If you look at the example code here, there's like 5 lines of pretty simple Rayon code that's almost a drop-in replacement for single threaded iterator code. It performs almost as good as the OpenMP C++ code, and it's guaranteed to be safe.

Re:Comparing Parallel Rust and C++ by _pferreir_ on Thursday November 07, 2019 @05:48AM (#21472087)
It's not the most readable Rust code I've ever seen and I guess that's not the main concern here. That said, I guess people find C++ easier because they're already used to the syntax.
Re:Comparing Parallel Rust and C++ by blub on Thursday November 07, 2019 @06:09AM (#21472177)
Even an amateur C++ programmer or C programmer would understand what that C++ code does. The only slightly opaque thing is the std::tie call. I'd feel comfortable having one of my C-focused colleagues modifying that C++ code.

The Rust code is... typical Rust. The algorithm almost gets lost in the specific peculiarities.

Re:Comparing Parallel Rust and C++ by the_why_of_y on Thursday November 07, 2019 @07:26AM (#21472547)
The first thing an amateur C++ programmer would notice is that that code isn't standard C++ code, what with its weird "#pragma omp" thing that isn't in the index of the Stroustrup book.
Re:Comparing Parallel Rust and C++ by gpderetta on Thursday November 07, 2019 @07:33AM (#21472594)
the nice thing about those pragmas is that the code has can be understood even if you ignore them. I do not know if this is true for all omp pragmas (IIRC some the newer ones might have some non ignorable semantics) but it is true for this omp for.
Re:Comparing Parallel Rust and C++ by the_why_of_y on Thursday November 07, 2019 @07:58AM (#21472755)
Yes, of course - a language extension can often give you better ergonomics than a library interface, both in implementing the code and in diagnostics reporting. The downside is that it's more effort to implement a language extension, it's more difficult to evolve it, and it restricts user's choice of implementation to those that have implemented the extension. For example, Microsoft Visual C++ supports only OpenMP 2.0, from 2002.

An interesting question in this context would be, is there anything preventing adding an OpenMP extension to Rust?

Re:Comparing Parallel Rust and C++ by gpderetta on Thursday November 07, 2019 @08:58AM (#21473187)
Of course there is a cost in making something part of the language, and the C++ way has always been to put features in the library whenever possible.

Regarding choice of implementation, there are more C++ compilers that support OpenMP than rust compilers.

Re:Comparing Parallel Rust and C++ by pcwalton on Thursday November 07, 2019 @10:36AM (#21474096)
Rayon is basically the "OpenMP of Rust" already.

OpenMP is designed around C-style for loops, which Rust discourages.

Re:Comparing Parallel Rust and C++ by gpderetta on Thursday November 07, 2019 @11:05AM (#21474391)
FWIW OpenMP supports any C++ random access iterator and c++11 range-for loops. I guess you count any external iterator as C-style loop.
Re:Comparing Parallel Rust and C++ by MauranKilom on Thursday November 07, 2019 @11:41AM (#21474754)
*newer OpenMP versions. MSVC is stuck on OpenMP 2.0 in which you can't even use unsigned integers as loop variable. No, seriously.
Re:Comparing Parallel Rust and C++ by petschge on Thursday November 07, 2019 @12:39PM (#21475274)
MSVC is hilariously bad and not used in HPC code. Not sure how much high performance game code is compiled with it.
Re:Comparing Parallel Rust and C++ by pcwalton on Thursday November 07, 2019 @12:42PM (#21475314)
A lot. I don't think OpenMP is used much in games.
Re:Comparing Parallel Rust and C++ by neutronicus on Thursday November 07, 2019 @04:26PM (#21477469)
Yeah OpenMP is mostly for problems with much less data-dependency than games.
Re:Comparing Parallel Rust and C++ by imtringued on Thursday November 07, 2019 @06:59PM (#21478767)
Rayon only covers a fraction of OpenMP's features.
Re:Comparing Parallel Rust and C++ by timvisee on Thursday November 07, 2019 @06:01AM (#21472143)
I think Rust is actually very readable in general.

In this snippet the author went through some insane optimization, and opted to use quite a few attributes, those definitely make it look noisy in this case. FFI bindings are verbose and not so clean either.

Re:Comparing Parallel Rust and C++ by rat9988 on Thursday November 07, 2019 @05:52AM (#21472108)
I don't think it is very hard to parse. I think it is very ugly though. Which kind of makes it unreadable. I mean reading fn is not natural for me. Reading function is way more natural. I feel like the language designers didn't pay attention at all to how natural it will look to developers
Re:Comparing Parallel Rust and C++ by pcwalton on Thursday November 07, 2019 @10:37AM (#21474101)
> I feel like the language designers didn't pay attention at all to how natural it will look to developers

This is not true. We agonized over syntax decisions. "fn" was actually preferred by most of the Rust community.

Re:Comparing Parallel Rust and C++ by jandrese on Thursday November 07, 2019 @01:12PM (#21475674)
I've had the impression that Rust developers come from a more pure-math background than most language designers. People who read mathematical notation all day probably find Rust to be more natural than a typical programming language. For people coming from a traditional computer language background the number of sigils on each line is a point of pain.

IMHO Rust may have tried to roll a little too much into the language. It has the air of the second system effect to it, where every good idea from every language is added together to get something that is less than the sum of its parts and you get code that is hard to decipher until you've learned a full college course worth of syntax.

Re:Comparing Parallel Rust and C++ by pcwalton on Friday November 08, 2019 @12:01AM (#21480073)
I designed the lifetime syntax and I'm far from having a pure math background. There aren't any sigils in Rust that C doesn't have, other than the lifetime syntax, which needs separate syntax as it's a novel feature.

Can you name a specific feature you want removed from Rust?

Re:Comparing Parallel Rust and C++ by jandrese on Friday November 08, 2019 @12:40PM (#21484663)
I'm not sure I'd want it removed, but generics tend to be pretty horrific looking to people new to the language.

An example:

  fn largest<T>(list: &[T]) -> T {
    let mut largest = list[0];

    for &item in list.iter() {
        if item > largest {
            largest = item;
        }
    }
I'm sure experienced Rust devs look at that and say it's fine, but that's definitely a hurdle for new developers.
Re:Comparing Parallel Rust and C++ by slavik81 on Friday November 08, 2019 @09:45PM (#21489220)
You need to specify the properties of T that you use. So, that first line should be:

  fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
https://tomtongue.com/docs/rust-wk-20.html#trait-bounds
Re:Comparing Parallel Rust and C++ by pcwalton on Friday November 08, 2019 @02:22PM (#21485745)
What would you want to see instead? That's pretty much the same syntax as generics in Java.
Re:Comparing Parallel Rust and C++ by blub on Thursday November 07, 2019 @10:46AM (#21474185)
Then the only reasonable conclusion is that the Rust community has different tastes compared to the mainstream programming community. To put it euphemistically.

The Swift team probably also agonized over syntax decisions and they came up with something very different which has won over many people and attracted little criticism.

Re:Comparing Parallel Rust and C++ by pcwalton on Thursday November 07, 2019 @11:01AM (#21474335)
The only concrete thing I've seen brought up so far is that some people don't like the keyword "fn". Swift chose "func". Is there really a huge difference? (I prefer "fn", by the way.)

Swift also doesn't have pervasive use of lifetimes like Rust does. Lifetimes, by their nature, always add some level of "noise".

Re:Comparing Parallel Rust and C++ by blub on Thursday November 07, 2019 @11:50AM (#21474826)
When people do make an effort and outline pain points, those are waved away by Rust programmers or deflected by claiming that they like said syntax choice.

At the end of the day though, these tiny thing like fn, or the lifetime annotations and the many others add up to an unpleasant experience and less readable code.

Re:Comparing Parallel Rust and C++ by pcwalton on Thursday November 07, 2019 @12:41PM (#21475305)
If Rust were an unpleasant experience, it wouldn't have users. I'm sorry that you disagree with the syntax decisions. We can't please everybody.
Re:Comparing Parallel Rust and C++ by blub on Thursday November 07, 2019 @02:33PM (#21476498)
I'm not an extremist, the language clearly has certain advantages. At the same time I do believe it could have a lot more users if it were a more pleasant experience.

If it becomes a mainstream language (like Java, C++, etc), I'd be happy to concede I was wrong. It could be that memory safety will trump ergonomics and it wouldn't be the first time that somewhat painful to use tools become very popular - see Linux, git, etc.

Re:Comparing Parallel Rust and C++ by rat9988 on Thursday November 07, 2019 @12:18PM (#21475074)
Lifetime annotations are an other ugly unreadable quirk. I'm happy to know I'm not the only one.
Re:Comparing Parallel Rust and C++ by pcwalton on Thursday November 07, 2019 @12:38PM (#21475264)
Those aren't syntax though. Without lifetimes you don't have memory safety without GC. There are plenty of languages that don't have memory safety, and plenty of languages with GC, but they don't broadly share Rust's goals.
Re:Comparing Parallel Rust and C++ by rat9988 on Friday November 08, 2019 @07:08AM (#21481529)
The problem is not lifetime but its annotation.
Re:Comparing Parallel Rust and C++ by rezeroed on Thursday November 07, 2019 @02:25PM (#21476430)
fn is great. I'm not at all mathematical as suggested by others. When I go back to Go I find myself wondering why I have to type the extra two characters.
Re:Comparing Parallel Rust and C++ by FpUser on Thursday November 07, 2019 @11:07AM (#21474422)
I would very much prefer function over fn , just for plain readability . Of course it is subjective but whatever.
Re:Comparing Parallel Rust and C++ by gpderetta on Thursday November 07, 2019 @04:39PM (#21477589)
Strupstup law is relevant here:

"For new features, people insist on LOUD explicit syntax. For established features, people want terse notation."

fn is fine.

Re:Comparing Parallel Rust and C++ by rezeroed on Thursday November 07, 2019 @02:28PM (#21476455)
fn usually appears at the start of a line following an empty line - how is it not readable? I honestly think even fn serves little purpose, other than compiler parsing. New paragraph == new function.
Re:Comparing Parallel Rust and C++ by FpUser on Thursday November 07, 2019 @06:30PM (#21478507)
Whatever tickles your fancy. To each their own
Re:Comparing Parallel Rust and C++ by leotaku on Thursday November 07, 2019 @11:12AM (#21474464)
I personally much prefer the smaller "fn" to "function". I started learning programming with python's "def", so maybe it comes from that.
Re:Comparing Parallel Rust and C++ by rat9988 on Thursday November 07, 2019 @12:15PM (#21475051)
def is way better than fn. you can read def at least.
Re:Comparing Parallel Rust and C++ by kbenson on Thursday November 07, 2019 @05:23PM (#21477953)
Read def? What the point of that? You might say "def" when you see it, but you think of the concept of a function. You should be translating fn to "function" in your head or if you speak it out loud, the same way you say "plus" when you see +. How do you "read" + otherwise? It's the same for every mathematical symbol, since there is no actual way to read them, since they communicate a concept that you most likely translate into your own language in your head.
Re:Comparing Parallel Rust and C++ by lenkite on Friday November 08, 2019 @08:40AM (#21482035)
Previous poster has a small point. Even I am guilty of saying 'f-n' when reading rust code alound. Kotlin is the best - all functions are fun
Re:Comparing Parallel Rust and C++ by saghm on Thursday November 07, 2019 @12:40PM (#21475293)
I'm not convinced that the C++ way is better here; either `fn` or `function` makes it clear that you're looking at a function (and incidentally makes it very easy to search for a function with a given name in a file), whereas just having the return type and then the function name makes it ambiguous until you read further whether you're looking at a variable or a function. If I see `fn size`, I know I'm looking at a function before I get to the parentheses, but if I see `int size`, that's still ambiguous until you go a character further.
Re:Comparing Parallel Rust and C++ by boring_twenties on Friday November 08, 2019 @01:41PM (#21485327)
Unfortunately, one character further is not enough to disambiguate the C++ syntax:

    int size();
Am I declaring a function returning an int? Or defining an object of type int and invoking the default constructor?
Re:Comparing Parallel Rust and C++ by bschwindHN on Thursday November 07, 2019 @04:56PM (#21477736)
fn vs. function is probably the least of your concerns when reading and writing rust. Lifetimes, generic parameters, and complex where clauses are what will throw you.

But if you spend enough time with the language it gets easy enough for these to not be a concern. I personally think it's very much worth learning.

Re:Comparing Parallel Rust and C++ by thanatropism on Thursday November 07, 2019 @07:03AM (#21472401)
I’m still learning Rust but from the “looks department” I can say so far that it “looks like” a lot more like Python etc. than the other systems languages.

It’s almost like Rust starts from a functional programmer’s perspective and adds the necessary complexity to have a “low level” language, whereas C is a simplified assembler and C++ tries to add “high level” amenities.

Re:Comparing Parallel Rust and C++ by vhakulinen on Thursday November 07, 2019 @05:50AM (#21472096)
I have the opposite: I know Rust, but I hardly know C++ beyond C (granted that I probably could figure out the not-so-easy c++ easier than I would figure out the rust version if I didn't know either). Don't get me wrong, I know what you mean. But the same can happen with many other languages too.
Re:Comparing Parallel Rust and C++ by cranej on Thursday November 07, 2019 @06:27AM (#21472241)
For me the Rust code is easy to read. Personally I don't think it's reasonable to ask programming languages 'easy to read for people not familiar with them' / 'read like English' / or something similar.
Re:Comparing Parallel Rust and C++ by StreamBright on Thursday November 07, 2019 @06:51AM (#21472333)
Why is that? The number one reason I do not like Rust is the use of ', & and so on to represent something that would be trivial to implement with plain English.

Example:

    struct HReq<'a> {
 
    }

    struct HReq<a: LifeTime> {
      
    }
Isn't that better?
Re:Comparing Parallel Rust and C++ by steveklabnik on Thursday November 07, 2019 @06:54AM (#21472344)
That doesn’t show the difference when you have more than one, and you also didn’t show how much more verbose the usage gets inside the struct.

It’s not a language level constraint to name lifetimes with a single letter. But folks tend to not use longer names for good reason.

Re:Comparing Parallel Rust and C++ by StreamBright on Thursday November 07, 2019 @06:58AM (#21472366)
I just have a hard time deciphering what the intention was with these single character things. Are you suggesting to use 'a_lifetime? What is that good reason? I usually use longer names to help the next person reading my code.
Re:Comparing Parallel Rust and C++ by steveklabnik on Thursday November 07, 2019 @07:08AM (#21472439)
Rust was originally implemented in OCaml, and takes a lot of inspiration from it. The ‘a syntax is used by OCaml for generic type parameters.

Rust is in a weird spot because we have two different kinds of generic parameters: types and lifetimes. They need to be distinguished from one another somehow. Nobody loves the lifetime syntax, but nobody has ever proposed something that would end up significantly better.

I’m not proposing you should use ‘a_lifetime, I’m saying you could. In the end, it ends up obscuring more than helping.

Re:Comparing Parallel Rust and C++ by kccqzy on Thursday November 07, 2019 @12:57PM (#21475504)
That would mislead people into thinking it's a type variable satisfying a trait called LifeTime instead of a lifetime variable. It would be confusing.
Re:Comparing Parallel Rust and C++ by xlc0212 on Thursday November 07, 2019 @05:47AM (#21472078)
How is C++ code better? Rust code is harder to write, but I don’t find it harder to read.
Re:Comparing Parallel Rust and C++ by lugg on Thursday November 07, 2019 @05:51AM (#21472105)
Rust is a very terse language. Inexperienced devs tend to write overly compressed code.

That example isn't too bad once you're used to the syntax and idioms but the lack of white space to space out logical blocks is what's making it hard to read.

Well, that and only what I can say equates to writing C++ in rust, much the same way you can write php in JavaScript if you squint hard enough.

Probably doesn't help it's trying to be a comparison which doesn't really work. A lot of that could be refactored out into idiomatic rust and it wouldn't look so bizarre.