News for hackers. Stuff that matters.
Re:Reducing Rust Incremental Compilation Times on macOS by nitsky on Sunday April 18, 2021 @09:27AM (#26852246)
If monomorphization is the killer, has the rust team considered adding a flag to compile all generics as trait objects in debug mode? Maybe there are some reasons this is impossible I haven’t thought of.
Re:Reducing Rust Incremental Compilation Times on macOS by steveklabnik on Sunday April 18, 2021 @09:32AM (#26852290)
People have asked, but only some traits are object safe, for example. Maybe someone could come up with a way to make it work, but nobody has attempted to put in that work, and it would be much more complex than "oh just make this flag run the "trait object" codegen instead of the "monomorphization" codegen."

Also, in general, we don't like flags that change language semantics. This one might be acceptable though, but I'm not on the lang/compiler teams.

Re:Reducing Rust Incremental Compilation Times on macOS by anchpop on Sunday April 18, 2021 @12:10PM (#26853671)
Why would it change language semantics? Haskell’s polymorphism to my eye seems about the same as rust’s, and it doesn’t need to worry about object safety
Re:Reducing Rust Incremental Compilation Times on macOS by iudqnolq on Sunday April 18, 2021 @12:36PM (#26853926)
Haskell's polymorphism isn't the same as rust. Rust has two kinds of polymorphism.

Static dispatch:

  fn show<T>(a: T) -> String
  where T: Display
  {
    Display::fmt(a)
  }

  fn main() {
    show(1_i32);
    show(1.0_f32);
  }
is (handwaves) first translated to a version with no generics

  fn show_i32(a: i32) -> String {
    i32::fmt(a)
  }

  fn show_f32(a: f32) -> String {
    f32::fmt(a)
  }

  fn main() {
    show_i32(1_i32);
    show_f32(1.0_f32);
  }
You can probably see how the more permutations of functions you need to generate the slower it gets.

Dynamic dispatch:

  fn show(a: Box<dyn Display>) -> String {
    Display::fmt(a)
  }

  fn main() {
    show(1_i32);
    show(1.0_f32);
  }
This translates to (handwaves):

  fn show(a: Box<dyn Display>) -> String {
    let fmt_fn = lookup_fn(Display::fmt, typeid_of(a))
    fmt_fn(a)
  }

  fn main() {
    show(1_i32);
    show(1.0_f32);
  }
This is simple to compile, but you need to do some extra work at runtime.
Re:Reducing Rust Incremental Compilation Times on macOS by gpderetta on Sunday April 18, 2021 @01:46PM (#26854651)
That's not an answer though. I believe (but I know little of both Haskell and Rust) that Haskell polymorphism is at least as powerful as rust static polymorphism but it is normally implemented via type erasure.

I think the real reason is that rust gives additional guarantees about lack of allocation and object layout that are hard to implement with dictionary passing (BitC tried and failed).

Re:Reducing Rust Incremental Compilation Times on macOS by Tyr42 on Sunday April 18, 2021 @03:30PM (#26855540)
I agree somewhat, in Haskell you can write generic functions without traits, and I think they are not monomorphized. (map for example.)

However, I think these all operate on boxed objects, which is a little bit easier to do than for Rust, where only some objects are boxed.

In short, I agree.

Re:Reducing Rust Incremental Compilation Times on macOS by steveklabnik on Sunday April 18, 2021 @12:21PM (#26853776)
I mean, object safety is one exact example. Every trait can be monomorphized, but not all traits can be made into an object. So "turn every generic into an object" just doesn't work. When you request a generic bound, you're saying that you want certain performance characteristics.

Haskell's polymorphism is similar, it's true, but I can't speak to their semantics well enough to intelligently comment. They are much less concerned with performance than Rust is, so they tend to do less of the sorts of optimizations that gets Rust into trouble here.