4 ms·
Swift has a typealias keyword but it's not really useful for this since two distinct aliased types with the same underlying type can be freely interchanged. Wro
by frankus 1y ago
Swift has a typealias keyword but it's not really useful for this since two distinct aliased types with the same underlying type can be freely interchanged. Wrong code may look wrong but it will still compile.
Wrapper structs are the idiomatic way to achieve this, and with ExpressibleByStringLiteral are pretty ergonomic, but I wonder if there's a case for something like a "strong" typealias ("typecopy"?) that indicates e.g. "this is just a String but it's a particular kind of String and shouldn't be mixed with other Strings".
- titanomachy 1y agoYeah, most languages I've used are like this. E.g. rust/c/c++. I guess the examples in TFA are golang? It's kind of nice that you don't have to define those wrapper types, they do make things a bit more annoying. In C++ you have to be extra careful even with wrapper classes, because types are allowed to implicitly convert by default. So if Foo has a constructor that takes a single int argument, then you can pass an int anywhere Foo is expected. Fine as long as you remember to mark your constructors as explicit.
- ameliaquining 1y agoBoth clang-tidy and cpplint can be configured to require all single-argument constructors (except move, copy, and initializer-list constructors) to be marked explicit, in order to avoid this pitfall.
- ghosty141 1y agoRust has the newtype idiom which works as proper type alias most of the time
- ameliaquining 1y agoIn what precise way are you envisioning that this would be different from a wrapper struct?
- frankus 1y agoPretty much only less boilerplate. Definitely questionable if it's worth the added complexity. And also it could probably be a macro.
- dataflow 1y agoThis sounds elegant in theory but very thorny in practice even with a standards change, at least in C++ (though I don't believe the issues are that particular to the language). Like how do you want the equivalent of std::cout << your_different_str to behave? What about with third-party functions and extension points that previously took strings?
- jandrewrogers 1y agoIsn't that where C++20 concepts come in?
- qcnguy 1y agoHaskell has this, it's called newtype. In OOP languages as long as the type you want to specialize isn't final you can just create a subclass. It's cheap (no additional wrappers or boxes), easy, and you can specialize behavior if you want to. Unfortunately for various good reasons Java makes String final, and String is one of the most useful types to specialize on.
- buerkle 1y agoBut then you are representing two distinct types as the same underlying type, String. MyType extends String; void foo(String s); foo(new MyType()); // is valid Leading to the original problem. I don't want to represent MyType as a String because it's not.
- qcnguy 1y agoIt has to work that way or else you can't use the standard library. What you want to block is not: StringUtils.trim(String foo); but myApp.doSomething(AnotherMyType amt); The latter is saying "I need not any string but a specific kind of string".