Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Hypothetical C++: easy type creation (spiria.com)
25 points by pierrebai on Jan 31, 2019 | hide | past | favorite | 11 comments


Sounds a bit like Haskell's newtype and its class derivation.

Using single-member structs (as explained in [0]) gets you the basic idea, but that's still missing the automatic lifting of the functions of your underlying element. I'm not sure if there is a sane way to do this given the current ecosystem. Perhaps a syntax like `newtype Celsius = int using std::{+, -, abs}` would work?

[0]: https://blog.nelhage.com/2010/10/using-haskells-newtype-in-c...


In Rust, using the newtype pattern is fairly common, but doesn't have explicit support. It's typically done as a single-member tuple.

Maybe support will be added later?


Good discussion and I would love more lightweight type creation in C++.

The "Allow internal functionality" proposal doesn't fully work as-is. Imagine you have a type Scalar, which has a function:

  Scalar Scalar::scale(Scalar);
If you now do

  typedecl Scalar Celcius;
you'd get a function for it with the following signature:

  Celcius Celcius::scale(Celcius);
However, the function you'd actually want is

  Celcius Celcius::scale(Scalar);
The root problem here is that since the original type mixes different uses of the type, you can't blindly convert all those uses to the new type.


This is discussed in the section about including external functionality through a mechanism of guided mapping. In the proposed syntax, that would be done like this:

    typedecl Celsius clone Scalar Scalar::scale(Scalar) -> Celsius Celsius::scale(Scalar);
(In the blog post, the example given is with std::pow())


These are called "strong/opaque typedefs". There have been multiple proposals in the past to add them to C++ over the years (N1706, N1891, N3515, N3741, P0109); the main roadblock is that most people would like to allow to edit a type's interface after creating the new type (for example, by preventing the sum of two int-like ProgramVersions), which is for example non-trivial for primitive types. It should also of course work for non-primitive types, which introduces lots of interactions with inheritance, templates, and so on.

As another possible way to achieve this, here's the huge proposal to add C++ metaclasses, which I'm personally not really a fan of, since it looks like it would add an additional third language on top of C++.

Thus, the general opinion is that everybody would like that feature in one form or another, but it's quite impossible to find a consensus on what the feature would look like.


Also called "newtype".



There are already units libraries for C++ that go further than this, including dimension checking (e.g. a velocity type divided by a time type gives an acceleration typed result with correct units). This extension idea doesn't seem to offer much over existing library solutions, though it might make writing those libraries a bit easier.


This is already possible even in vanilla C:

Friday Q&A 2013-08-02: Type-Safe Scalars with Single-Field Structs

https://mikeash.com/pyblog/friday-qa-2013-08-02-type-safe-sc...


Yeah but it is a pain.


A tiny thing, but one of my favorite features of Go. "type FooId int" -- zero fuss, zero muss, much clearer and safer code.




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

Search: