4 ms·
I think it's also aimed at the C++ crowd where generics = static dispatch and interfaces = dynamic dispatch and people try to eek out the extra performance.
by uluyol 5y ago
I think it's also aimed at the C++ crowd where generics = static dispatch and interfaces = dynamic dispatch and people try to eek out the extra performance.
- eru 5y agoKeep in mind that C++ doesn't provide for parametric polymorphism, one of the more important uses of generics. Parametric polymorphism gives you guarantees about your program for free. C++'s templates can't do that. In C++ even if the types look generic, your code can make assumptions about the types. Eg your generic code from some type 'a' to some type 'a' can implement the identify function for most types, but implement cosine when given a float. In something like Haskell (or Java, I think?) that sneakiness is not possible without clearly telling the user in the type. See eg https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/ https://bartoszmilewski.com/2014/09/22/parametricity-money-f...
- kaba0 5y agoIsn’t it being (have been) remedied by C++’s constraints?
- tialaramex 5y agoC++ 20 Concepts are duck typed. Inertia means it isn't practical to ship something with the semantics of say, Rust's Traits. Your own concepts could (but most will not) choose to abuse the duck typing to require a "marker" e.g. the natural way to define Gunfighter might be to say it has a draw() function, and we could imagine instead adding a marker named "is_a_Gunfighter" to every Gunfighter. However the built-in concepts intentionally do not do that. Instead C++ documents a "model" for the standard concepts and explains that it is, as so often, the programmer's responsibility to ensure that everywhere their code need a concept they use things which correctly model the concept, the compiler will only do duck typing. So, in Rust an f32 isn't Ord (the totally ordered Trait) because well, NaN != NaN. So if you ask Rust's default slice sort to sort a slice of f32s that won't compile - what if the slice has a NaN in it? You will need to either remember that sorting IEEE floating point numbers isn't generally a reasonable thing to do, or, explicitly write your deterministic compare function (maybe as a lambda) and call sort_by() with your comparison. Now it's obvious whose fault it is when your function blows up for NaN. In C++ the float type is in fact std::totally_ordered and it's your fault if you ever end up with a NaN somewhere and it matters.
- josefx 5y ago> C++'s templates can't do that. In C++ even if the types look generic, your code can make assumptions about the types. If you want an assertion that a class pretends to implement certain semantics (a.k.a. implements an interface) then you can have a specialized struct that has to be declared for every class used with your template. Either the user provides it and guarantees that their identity() function implements the required semantics of identity() or he doesn't and the code fails to compile. You could also check explicitly if the template parameter type inherits from a certain interface type, but that tends to exclude a lot of types that do not generally implement any interface explicitly, cant remember an IIdentityProviderFactoryBuilderManagementJavaJXBeanObserverInterface on int for example.
- eru 5y agoGoing via the interface route that you described doesn't rescue C++ here. The thing that parametric polymorphism gives you is that the type system can ensure that your code is not doing anything with your values but pass them around. And you don't need to read nor trust any implementation code for that. For what you describe you could still implement cosine for float, and 'not' for bools, and identity for char. We don't want the class to implement certain semantics. We'd want an assurance that certain semantics are _not_ implemented (in some sense). We want an assurance that the code is forced to treat the value as an opaque black box.