On Thu, 30 Dec 2010 14:39:02 +0100 Lutger Blijdestijn <lutger.blijdest...@gmail.com> wrote:
> Guilherme Vieira wrote: > > > On Thu, Dec 30, 2010 at 9:24 AM, bearophile > > <bearophileh...@lycos.com>wrote: > > > >> Jonathan M Davis: > >> > >> > typedef is definitely on the way out, so that's not a solution, > >> > >> typedef is deprecated (because its semantics is not flexible enough and > >> because it doesn't play well with object oriented language features), but > >> I have a real need for something like it. Andrei has discussed about a > >> Phobos-based typedef replacement (based on structs + alias this), but > >> nothing concrete has come out yet. I hope to see something to solve > >> problems like spir ones. > >> > >> > >> > and it would be a pretty fragile one IMHO anyway. > >> > >> Please, explain better. > >> > >> Bye, > >> bearophile > >> > > > > As far as I know, typedef was a form of "discriminated alias". I don't > > know the reasons for its deprecation. It just occurred to me that D's > > typedefs + templates could be quite handy in this case. > > > > Consider: > > > > struct semantic_wrapper(T) > > { > > this(T value) { this.value = value; } > > > > T value; > > } > > > > typedef semantic_wrapper!(int) Position; > > typedef semantic_wrapper!(size_t) Count; > > typedef semantic_wrapper!(string) Filename; > > typedef semantic_wrapper!(string) DirPath; > > > > void func(Position pos) { ... } > > void func(Count c) { ... } > > void func(Filename fname) { ... } > > void func(DirPath dir) { ... } > > > > void main() > > { > > func(Position(1)); // calls first overload > > func(Count(5)); // calls second > > func(Filename("file.txt")); // third > > func(DirPath("/dev/null")); // fourth > > > > func(1); // fails > > func("blah"); // fails > > } > > > > > > Requires a little more typing, but sometimes it can be better than > > creating a new function name (which can get extra-big, non-telling or > > both) or than creating factory methods (which I personally dislike, > > although it's just a matter of taste most of the time; sometimes you may > > want to instantiate from inside a template and classes needing factories > > would not work, for example, but one could argue on the validity of this > > anytime). > > > > Just giving my 2 cents. Dunno if I missed some detail. > > > > Here is an attempt to implement it, still needs support for writeln and > lacks some details: > > import std.stdio; > > mixin template Newtype(T, string typename) > { > mixin("struct " ~ typename ~ " { alias base this; " ~ T.stringof ~ > " base; @disable void opAssign(" ~ T.stringof ~ ") {} }"); > } > > mixin Newtype!(int, "Position"); > mixin Newtype!(size_t, "Count"); > mixin Newtype!(string, "FileName"); > mixin Newtype!(string, "DirPath"); > > void func(Position pos) { writeln("position: ", pos.base ); } > void func(Count c) { writeln("count:", c.base); } > void func(FileName fname) { writeln("filename:", fname.base); } > void func(DirPath dir) { writeln("dirpath:", dir.base); } > > void func2(int pos) { writeln("position: ", pos); } > > void main() > { > > func(Position(1)); // calls first overload > func2(Position(1)); // implicit conversion to int with alias this > func(Count(5)); // calls second > func(FileName("file.txt")); // third > func(DirPath("/dev/null")); // fourth > func(1); // fails > func("blah"); // fails > > auto p = Position(1); > p = 2; // fails > p.base = 4; // ok, explicit > } I like very much the template mixin solution. Would there be any difference in inheriting an interface (or even a plain type)? Also, can one presently rewrite this in D without _string_ mixin inside the template? (Else this solution is simply not acceptable for me: I'm allergic to code in strings; but don't ask me why ;-) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com