4 ms·
An interesting post. I have two thoughts. The first is in response to: > I think to some extent Rust has tried to cheat this by making non-zero cost abstracti
by thenewwazoo 7y ago
An interesting post. I have two thoughts.
The first is in response to:
> I think to some extent Rust has tried to cheat this by making non-zero cost abstractions actively unpleasant to write, making it feel like the zero cost abstraction is better.
This idea is closely related to a comment by estebank just yesterday[1]. I disagree - I think Rust makes non-zero-cost abstractions obvious to the author. If you want to do something in a way that's costly, the language surfaces that information. It puts it right in your face and makes you deal with it. That's a good thing. It makes for better code. If you want to use dynamic dispatch, you can't pretend you're not.
The second is to add a place where I think Rust has gotten zero cost abstractions right: zero-sized generic types. I use them extensively in embedded code to build things like states. I can use trait methods and associated consts in really powerful ways to encode complicated relationships that constrain the operation of a peripheral at compile time, and it compiles down to a single register access. That's crazy powerful. Using C structs and type punning can do the same thing, but without the safety. Using C++'s classes can give me some type safety, but at the cost of real method call overhead. I get giddy every time I think about writing something like
struct Adc<PIN: AdcPin, MODE: AdcMode>();
let adc = Adc(adc_pin, AdcModes::8Bit);
and the compiler will let me know if my `adc_pin` isn't the right type.
[1] https://news.ycombinator.com/item?id=19920945 https://news.ycombinator.com/item?id=19920945
- ridiculous_fish 7y agoWhy would a C++ version involve method call overhead? Wouldn't C++ actually be more straightforward with its value-typed template parameters?
- thenewwazoo 7y agoWith C++, wouldn't I need to either use a virtual base class with a typed template parameter (to emulate interfaces), or need to use duck-typed parameter and lose type safety?
- kccqzy 7y agoSprinkle in a bunch of std::enable_if to do SFINAE and that's it. It's a way to tell the compiler a certain function or method should be enabled only when some other compile-time condition is true.
- gmueckl 7y agoWhich of the two template arguments are you talking about? The enum-typed template argument will lead to a optimized specialization of the template. C++ does, however, have an unfortunate problem with restricting type parameters to types with certain properties/guarantees in ways that won't make the compiler explode in obtuse error messages.
- llukas 7y agostatic_assert, enable_if or just plain not providing default implementation and only specializations, as everything in C++ error messages is something you can customize to high extent...
- orbifold 7y agoYou don’t have to use a virtual base class. You can implement interfaces statically by passing in the implementation as a template parameter.
- comex 7y agoRust is getting value-typed template parameters Real Soon Now - in fact, they now work to some extent on nightly. In the parent’s example, my guess is that only the second parameter could be changed to a value, whereas the first is actually used somewhere as a type - but I have no context so it’s just a guess.
- pjmlp 7y agoOnly if you don't make proper use of template value types and inline calls with static dispatch. There are quite a few embedded C++ talks about how to go at it.
- jcelerier 7y agowhich is exactly how you would do it in C++ : https://www.embedded.com/design/programming-languages-and-tools/4428377/2/Objects--No--thanks---Using-C--effectively-on-small-systems- https://www.embedded.com/design/programming-languages-and-to...