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

If you like doing compile time things with types like typescript enables then Nim is fantastic. I've been learning Rust recently and I'm continually disappointed with how little compile time or type based stuff you can do.


With prior C++ experience it's easy to equate C++ templates and Rust generics (similar syntax - usually does similar things - quack like ducks etc.); I know I did. And through this lens generics will soon seem very limited compared to templates. But the underlying reason for this is because C++ templates aren't generics - they're much closer semantically to hygienic, declarative macros. C++ templates are based around rules like SFINAE and allowing multiple alternatives and the compiler will work out which is the most-specific match that works. C++ templates (even with concepts) are unconstricted - when you give a template a type, there aren't any checks enforced by the language about the types; many templates have a list of requirements and you, the programmer, have to check them, unless the template itself has guards and checks the types.

Through this lens, the semantic equivalent of C++ templates in Rust isn't generics, but macro_rules! - but for most uses of C++ templates you would rather use generics and traits.


Yah the type level programming in Rust really is limited to traits which provide little compile time functionality. It's pretty straight jacketed which is nice in some ways as you wont have un-anticipated interactions with user types. On the downside that limits un-anticipated usage of libraries or types.

Even macro_rules! aren't as capable as modern C++ templates with types. I am let down with how lacking Rust is when doing compile time type based programming. There's no CTTI or RTTI in Rust. The procedural macros don't have access to type information, just syntax. The constexpr equivalents are so limited, etc.


Yep, true. Stuff like Zig's famous MultiArrayList, where you write pretty simple Zig code to take apart and reify types and functions just doesn't seem to be much of a thing for Rust by design. Procedural macros also have build time issues, because the macro must be fully compiled before any code using it can be compiled (hence why they must be put in a separate crate), and as I understand it procedural macros only get TokenStreams, so if they want to work with Rust code, they must re-create the AST from tokens with their own parser. Unfortunately, derive macros also happen to be procedural and subject to those limitations, handy as they may be.

What I really like about Rust generics on the other hand is that, while limited in many ways, those limitations allow them to be complete in the sense that as far as types concerned, the generic signature is the law of the land; it'll compile with any type fulfilling the trait bounds, and the implementation behind the signature is fully limited to exactly what's provided by the trait bounds.




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

Search: