Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Perhaps this is subverting the type-theoretic (in a CS sense) point being made, but in C++ you could quite reasonably write a function:

  template<typename T>
  T fn(T t){
      return t * 2;
  }

  fn(4.2); //fine
  fn("foo"); //fails
because the inability to multiply by 2 isn't a problem until an incompatible type parameter is instantiated. Is this not the case in rust?


Nope in Rust you can only do things with generic types that fit the constraints(called trait bounds in Rust) you've placed on them. So with no constraints you can only do things that every single type supports. In essence it's an implicit vs explicit trade off. C++ implicitly figures out the constraints on generic types whereas Rust requires you to be explicit about them.

Your example in Rust would be

    use std::ops::Mul;
    
    fn double<T: Mul<i32>>(a: T) -> T::Output {
        a * 2
    }
    
    fn main() {
        println!("{}", double(2));
    
        // Can't double &str because it doens't implement Mul<i32>
        // println!("{}", double("Hello"));
    }



https://play.rust-lang.org/?gist=ba8d6368a7fb997586b51580baa...

Also as the GP points out the above fact is crucial for the reasoning around to hold `fn<T>(T) -> T`. An example that breaks those rules is

    fn thing<T: Default>(a: T) -> T {
        T::default()
    }


That's because templates have no type-checking in C++.

Ideally, you wouldn't be able to do this with concepts, but I don't know whether that's true for the concepts that finally made it into the standard (i.e. I don't know if it would be an error to call a function or operator on an argument if that function isn't required in the concept specification.).


C++ templates have type checking after expansion, the type checking just isn’t modular.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: