News for hackers. Stuff that matters.
Re:“Modern” C++ Lamentations by leggomylibro on Friday December 28, 2018 @01:20PM (#18778433)
In many ways the '++' in 'C++' comes from giving the compiler more information to work with. You can opt to trust the compiler much more than in C, and the idea is that you gain time at develop-time and hopefully run-time with the tradeoff of losing it at compile-time.

At least, that's how I've usually understood it. And the example you mention seems like a complaint with C++20's Ranges in particular. I guess I'd fall into the, "but can't you just ignore the parts you don't like?" camp.

This post is written in the context of game engines, but I see a lot of the same 'OG C' arguments made when people in embedded development resist giving C++ a try.

We're all writing resource-constrained applications that work on tight time budgets, and none of us feel comfortable throwing up our hands and 'trusting the compiler' in that sort of atmosphere. But C isn't getting any younger, and it's hard to do polymorphism without getting hack-y.

Now, who's turn is it to advocate Rust?

Re:“Modern” C++ Lamentations by blattimwind on Friday December 28, 2018 @02:57PM (#18779021)
> At least, that's how I've usually understood it. And the example you mention seems like a complaint with C++20's Ranges in particular. I guess I'd fall into the, "but can't you just ignore the parts you don't like?" camp.

The issue is that many libraries (including std/stl) tend to produce long compile times.

Re:“Modern” C++ Lamentations by arka2147483647 on Friday December 28, 2018 @02:35PM (#18778880)
> You can opt to trust the compiler much more than in C,

I feel that in modern C++ modern style ”trust the compiler” often means ”leave the programmer out of the loop”

I really, really would hate to have to try to debug the ranges example, for example.

Re:“Modern” C++ Lamentations by lambda on Friday December 28, 2018 @08:39PM (#18781113)
Here's an implementation that is equivalent to the modern C++ example (playground link: https://play.rust-lang.org/?version=stable&mode=release&edit...):

  use std::time::SystemTime;

  fn main() -> Result<(), Box<dyn std::error::Error>> {
      let t0 = SystemTime::now();

      let triples = (1..).flat_map(|z|
          (1..=z).flat_map(move |x| 
              (x..=z).filter_map(move |y|
                  if x * x + y * y == z * z {
                      Some((x, y, z))
                  } else {
                      None
                  }
              )
          )
      );
    
      for triple in triples.take(100) {
          println!("{:?}", triple);
      }
    
      let elapsed = t0.elapsed()?;
    
      println!(
          "{}", 
          elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 * 1e-9
      );
    
      Ok(())
  }
It takes about .376s to compile in debug mode, about 0.491s in release mode. This was after warming caches; the first run took about 2.071s, of which a large portion was probably loading the compiler and standard library.

In debug mode, it runs in 0.047586s, in release mode, 0.002304.

I was pleasantly surprised to see this is actually better on the build times and debug build performance, given that those are two often cited sore points in Rust.

I would also say that while this is a little bit noisy, it is more readable than the proposed C++20 version. "1.." looks more like a range starting at 1 than "iota(1)" does. There's an actual "if" statement in there.

In fact, while Rust doesn't officially have generator/coroutine support yet, it is available in nightly builds for the implementation of async/await. If you use the nightly compiler, enable the unstable features, and wrap an adapter type around Generator that implements Iterator, you can write:

    let triples = IterGen(||
        for z in 1.. {
            for x in 1..=z {
                for y in x..=z {
                    if x*x + y*y == z*z {
                        yield (x, y, z)
                    }
                }
            }
        }
    );
It's expected that at some point in the coming year or so async/await, and probably the underlying Generator feature, will be stabilized, and I presume the standard library will implement the Iterator trait for appropriate types of Generators (though there is some bikeshedding about the details of that).

Rust doesn't have generators yet, so this is only really fair to compare to the generator/co_yield example in C++ (which is also proposed but not yet standardized). I'd say Rust's syntax compares favorably to that example; the ranges are more clear than the traditional C-style "for" loops, there's native tuple syntax, and it's just be "yield" instead of "co_yield".

Re:“Modern” C++ Lamentations by pjmlp on Saturday December 29, 2018 @03:25AM (#18782632)
Rust sore points regarding compile times have to do with lack of support for binary libraries.

While on C++ I can take advantage of incremental compilation and linking, while using binary libraries for all dependencies, with cargo I have always to build the whole world from scratch minus standard library.

Re:“Modern” C++ Lamentations by kodemizer on Saturday December 29, 2018 @03:32AM (#18782651)
I'm not sure when the last time you've used Rust is, but that hasn't been true in quite a while (not sure how long exactly). Cargo now has incremental compilation, and it's turned on by default. It's great!
Re:“Modern” C++ Lamentations by pjmlp on Saturday December 29, 2018 @03:51AM (#18782712)
I dabble on Rust regularly, usually during plane or train trips.

It still doesn't do incremental linking, and cargo still builds everything from scratch without any support for binary libraries.

Re:“Modern” C++ Lamentations by kzrdude on Saturday December 29, 2018 @08:28AM (#18783469)
Binary libraries don't help so much -- many libraries use generic types and functions (those are instantiated and compiled for each specific instance) which can only be delivered as library "metadata", not codegen'ed, and the latter is the very slow part.
Re:“Modern” C++ Lamentations by pjmlp on Saturday December 29, 2018 @09:06AM (#18783587)
Wrong since C++11 introduced external templates for common instatiation types.

Additionally, it is not like every C++ library is full of meta-programming templates.

Finally, there are other languages with library "metadata" and generic data types, which can easily beat Rust compile times like Delphi, Eiffel and Ada.

Re:“Modern” C++ Lamentations by pcwalton on Monday December 31, 2018 @06:55PM (#18797930)
Delphi and Eiffel compilers don't do anywhere near the same level of optimization as LLVM does.

And are you sure GCC's Ada has better compile times? My sense is that so few people use Ada at scale that we don't really know.

Re:“Modern” C++ Lamentations by swsieber on Friday December 28, 2018 @02:18PM (#18778801)
Me! Sort of.

Rust is definitely further along the scale towards the end of "giving more to the compiler so it takes longer". I usually like the trade. Most of the time.

Re:“Modern” C++ Lamentations by adrianN on Friday December 28, 2018 @03:47PM (#18779301)
Rust also has a saner module system that makes incremental builds much quicker. They're still pretty slow, but not as agonizingly slow as a clean build.
Re:“Modern” C++ Lamentations by nicoburns on Friday December 28, 2018 @05:22PM (#18779958)
Rust is only fast compared to C++ (and then only sometimes). Literally every other language is significantly faster to compile. I'm hoping this can change though. Rust with fast compile times and a more complete library ecosystem (and ideally better IDE support) would be an incredibly productive language.
Re:“Modern” C++ Lamentations by dzdt on Friday December 28, 2018 @06:40PM (#18780409)
Scala is slower to compile than C++ in large scale enterprise development. (The exception that proves the rule?)
Re:“Modern” C++ Lamentations by nicoburns on Saturday December 29, 2018 @09:34AM (#18783728)
Ah, I forgot about Scala. Someone below mentioned Haskell too (which I haven't used). Still, calling Rust fast seems wrong to me!
Re:“Modern” C++ Lamentations by aphexairlines on Friday December 28, 2018 @08:16PM (#18780985)
Compared with C++, Scala projects are not slow to compile when you use Gradle multi-project builds (with granular sub-projects) and Gradle build caching.
Re:“Modern” C++ Lamentations by swsieber on Saturday December 29, 2018 @12:16AM (#18782010)
Not as agonizingly slow, but still agonizingly slow.

While I do appreciate build speed improvements, saying that it's better than it was isn't a super high bar in terms of user experience.

I love Rust, I really do, but it's still incredibly slow. I'm excited for any progress it makes on this front.

Re:“Modern” C++ Lamentations by kodemizer on Saturday December 29, 2018 @03:34AM (#18782662)
I think the most promising thing on this front is Cranelift (https://github.com/CraneStation/cranelift). The idea is that, when cranelift is ready, we might use it for debug builds (but still use LLVM for release builds).
Re:“Modern” C++ Lamentations by SomeHacker44 on Friday December 28, 2018 @02:57PM (#18779023)
I was an early user of the language in the 80s and early 90s (with for example cfront which compiled to C and later the original g++ and its libg++).

> In many ways the '++' in 'C++' comes from giving the compiler more information to work with.

This is definitely not the origin of the '++'. I believe the '++' name was literally a play about "one better than C."