www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Library Typedefs are fundamentally broken

reply "Freddy" <Hexagonalstar64 gmail.com> writes:
When you have separate 2 typedefs of the exact same type, they
are equal.While this maybe able to be solved with
Typedef!(Typedef!(...)) different modules typedef ing the same
type (most likely build-in types) would have their typedef be
equivalent thereby degrading the purpose of typedef.
---
import std.typecons;

alias meter = Typedef!float;
alias feet = Typedef!float;
static assert(!is(meter==feet));
---
Your thoughts?
Sep 16 2014
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/16/14, 7:57 PM, Freddy wrote:
 When you have separate 2 typedefs of the exact same type, they
 are equal.While this maybe able to be solved with
 Typedef!(Typedef!(...)) different modules typedef ing the same
 type (most likely build-in types) would have their typedef be
 equivalent thereby degrading the purpose of typedef.
 ---
 import std.typecons;

 alias meter = Typedef!float;
 alias feet = Typedef!float;
 static assert(!is(meter==feet));
 ---
 Your thoughts?
Add a sequence number as a uint, defaulted to 0. -- Andrei
Sep 16 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 Add a sequence number as a uint, defaulted to 0. -- Andrei
See discussion: https://d.puremagic.com/issues/show_bug.cgi?id=12100 Bye, bearophile
Sep 16 2014
parent reply Andrej Mitrovic via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 9/17/14, bearophile via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 Andrei Alexandrescu:

 Add a sequence number as a uint, defaulted to 0. -- Andrei
See discussion: https://d.puremagic.com/issues/show_bug.cgi?id=12100
It's a good thing you found GCC and VC implement this. I think it's another sign that we could use this feature.
Sep 17 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 17 September 2014 at 07:21:13 UTC, Andrej Mitrovic 
via Digitalmars-d wrote:
 On 9/17/14, bearophile via Digitalmars-d 
 <digitalmars-d puremagic.com> wrote:
 Andrei Alexandrescu:

 Add a sequence number as a uint, defaulted to 0. -- Andrei
See discussion: https://d.puremagic.com/issues/show_bug.cgi?id=12100
It's a good thing you found GCC and VC implement this. I think it's another sign that we could use this feature.
Technically, they implement it via macro, and the macro re-expands on every use. It's mostly useless outside of ".cpp" files: The identifiers are unstable cross compilation units. And if it appears in a .h, it'll be re-expanded to a different value on every include. If it appears in a macro, it'll be expanded to something different on every macro use too.
Sep 17 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/17/2014 12:30 AM, monarch_dodra wrote:
 On Wednesday, 17 September 2014 at 07:21:13 UTC, Andrej Mitrovic via
 Digitalmars-d wrote:
 On 9/17/14, bearophile via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 Andrei Alexandrescu:

 Add a sequence number as a uint, defaulted to 0. -- Andrei
See discussion: https://d.puremagic.com/issues/show_bug.cgi?id=12100
It's a good thing you found GCC and VC implement this. I think it's another sign that we could use this feature.
Technically, they implement it via macro, and the macro re-expands on every use. It's mostly useless outside of ".cpp" files: The identifiers are unstable cross compilation units. And if it appears in a .h, it'll be re-expanded to a different value on every include. If it appears in a macro, it'll be expanded to something different on every macro use too.
It's implemented as a special macro named __COUNTER__ which expands to an integer literal, incremented each time. If such a thing were implemented in D, one could not depend on the values being globally unique, nor consistent when a module is compiled vs imported, nor consistent when multiple modules are compiled together vs compiled independently, nor even any predictable relationship between the values within a particular module (because semantic analysis is not supposed to be order dependent).
Sep 17 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 9/17/2014 2:37 AM, Walter Bright wrote:
 If such a thing were implemented in D, one could not depend on the values being
 globally unique, nor consistent when a module is compiled vs imported, nor
 consistent when multiple modules are compiled together vs compiled
 independently, nor even any predictable relationship between the values within
a
 particular module (because semantic analysis is not supposed to be order
 dependent).
You're probably better off simply using __LINE__ instead.
Sep 17 2014
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
I don't think I've used any kind of typedef for a long time. I 
prefer to just use a plain struct.
Sep 16 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Sep 17, 2014 at 03:05:57AM +0000, Adam D. Ruppe via Digitalmars-d wrote:
 I don't think I've used any kind of typedef for a long time. I prefer
 to just use a plain struct.
Yeah, I found structs + alias this far more useful than any kind of typedef. Due to the way alias this lookups work, you can basically "customize" the underlying type by defining the appropriate struct methods to shadow the underlying type's, thereby achieving a kind of "static inheritance". T -- Error: Keyboard not attached. Press F1 to continue. -- Yoon Ha Lee, CONLANG
Sep 16 2014
parent reply "Piotrek" <p nonexistent.pl> writes:
On Wednesday, 17 September 2014 at 05:40:22 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 On Wed, Sep 17, 2014 at 03:05:57AM +0000, Adam D. Ruppe via 
 Digitalmars-d wrote:
 I don't think I've used any kind of typedef for a long time. I 
 prefer
 to just use a plain struct.
Yeah, I found structs + alias this far more useful than any kind of typedef. Due to the way alias this lookups work, you can basically "customize" the underlying type by defining the appropriate struct methods to shadow the underlying type's, thereby achieving a kind of "static inheritance". T
Do you think it's worth to mention it in "Comments" section of the docs? Piotrek
Sep 17 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Sep 17, 2014 at 08:49:02PM +0000, Piotrek via Digitalmars-d wrote:
 On Wednesday, 17 September 2014 at 05:40:22 UTC, H. S. Teoh via
 Digitalmars-d wrote:
On Wed, Sep 17, 2014 at 03:05:57AM +0000, Adam D. Ruppe via Digitalmars-d
wrote:
I don't think I've used any kind of typedef for a long time. I
prefer to just use a plain struct.
Yeah, I found structs + alias this far more useful than any kind of typedef. Due to the way alias this lookups work, you can basically "customize" the underlying type by defining the appropriate struct methods to shadow the underlying type's, thereby achieving a kind of "static inheritance". T
Do you think it's worth to mention it in "Comments" section of the docs?
[...] Sure. Which page? T -- Why can't you just be a nonconformist like everyone else? -- YHL
Sep 17 2014
parent "Piotrek" <p nonexistent.pl> writes:
On Wednesday, 17 September 2014 at 21:03:26 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 On Wed, Sep 17, 2014 at 08:49:02PM +0000, Piotrek via 
 Digitalmars-d wrote:
 On Wednesday, 17 September 2014 at 05:40:22 UTC, H. S. Teoh via
 Digitalmars-d wrote:
On Wed, Sep 17, 2014 at 03:05:57AM +0000, Adam D. Ruppe via 
Digitalmars-d
wrote:
I don't think I've used any kind of typedef for a long time. 
I
prefer to just use a plain struct.
Yeah, I found structs + alias this far more useful than any kind of typedef. Due to the way alias this lookups work, you can basically "customize" the underlying type by defining the appropriate struct methods to shadow the underlying type's, thereby achieving a kind of "static inheritance". T
Do you think it's worth to mention it in "Comments" section of the docs?
[...] Sure. Which page? T
Now this is a good question :) http://dlang.org/library/std/typecons.html or http://dlang.org/library/std/typecons/Typedef.html Do we have any guideline for users comments? Moreover, I've just stared wondering if the new layout if officially released . Piotrek
Sep 17 2014
prev sibling next sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Wednesday, 17 September 2014 at 02:57:03 UTC, Freddy wrote:
 When you have separate 2 typedefs of the exact same type, they
 are equal.While this maybe able to be solved with
 Typedef!(Typedef!(...)) different modules typedef ing the same
 type (most likely build-in types) would have their typedef be
 equivalent thereby degrading the purpose of typedef.
 ---
 import std.typecons;

 alias meter = Typedef!float;
 alias feet = Typedef!float;
 static assert(!is(meter==feet));
 ---
 Your thoughts?
`Typedef` takes a second argument that can make it unique. It's all in the docs.
Sep 16 2014
parent "Freddy" <Hexagonalstar64 gmail.com> writes:
On Wednesday, 17 September 2014 at 03:08:46 UTC, Jakob Ovrum
wrote:
 On Wednesday, 17 September 2014 at 02:57:03 UTC, Freddy wrote:
 When you have separate 2 typedefs of the exact same type, they
 are equal.While this maybe able to be solved with
 Typedef!(Typedef!(...)) different modules typedef ing the same
 type (most likely build-in types) would have their typedef be
 equivalent thereby degrading the purpose of typedef.
 ---
 import std.typecons;

 alias meter = Typedef!float;
 alias feet = Typedef!float;
 static assert(!is(meter==feet));
 ---
 Your thoughts?
`Typedef` takes a second argument that can make it unique. It's all in the docs.
Sorry, my mistake.
Sep 16 2014
prev sibling next sibling parent reply "Jack Applegame" <japplegame gmail.com> writes:
You can use module name and line number as unique tag.
Sep 17 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 17 September 2014 at 10:00:31 UTC, Jack Applegame 
wrote:
 You can use module name and line number as unique tag.
This is exactly what I would have expected as default behaviour. Is anyone aware why this counter appoach was used instead?
Sep 17 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 Is anyone aware why this counter appoach was used instead?
It's not sound, it's a hack. Putting unreliable hacks in a standard library is very bad. It's even worse than the problems that Walter has listed for __COUNT__ (I didn't ask for that count in my enhancement request. If you have to copy it's often better to copy from Lisp/ML/Ada instead of C++). Bye, bearophile
Sep 17 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Wednesday, 17 September 2014 at 16:54:09 UTC, bearophile wrote:
 Dicebot:

 Is anyone aware why this counter appoach was used instead?
It's not sound, it's a hack. Putting unreliable hacks in a standard library is very bad. It's even worse than the problems that Walter has listed for __COUNT__ (I didn't ask for that count in my enhancement request. If you have to copy it's often better to copy from Lisp/ML/Ada instead of C++). Bye, bearophile
It is pretty much default technique used any time new template instance needs to be forced. Sound or not, I am not aware of any other even remotely reliable library approaches (it works pretty good for me actually).
Sep 17 2014
parent Andrej Mitrovic via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 9/17/14, Dicebot via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 It is pretty much default technique used any time new template
 instance needs to be forced. Sound or not, I am not aware of any
 other even remotely reliable library approaches (it works pretty
 good for me actually).
Actually, there is just one small issue with it (rare enough to almost never occur). Two instances on the same line will use the same line, e.g.: Foo!() x; Foo!() y; But there would be a simple way to fix this, by introducing __COLUMN__. But I don't know, it's using an AK47 to shoot a fly. There are more important enhancements I guess. :p
Sep 18 2014
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 9/17/2014 9:54 AM, bearophile wrote:
 Dicebot:

 Is anyone aware why this counter appoach was used instead?
It's not sound, it's a hack. Putting unreliable hacks in a standard library is very bad. It's even worse than the problems that Walter has listed for __COUNT__ (I didn't ask for that count in my enhancement request. If you have to copy it's often better to copy from Lisp/ML/Ada instead of C++).
Even worse? How? (Yes, I know that if you instantiate it twice on the same line, you'll get the same value.)
Sep 17 2014
parent "Dicebot" <public dicebot.lv> writes:
On Wednesday, 17 September 2014 at 17:16:55 UTC, Walter Bright 
wrote:
 Even worse? How? (Yes, I know that if you instantiate it twice 
 on the same line, you'll get the same value.)
To address the latter I usually implement it as a string token that defaults to __MODULE__ ~ ":" ~ to!string(__LINE__) but still can be manually specified by the user. It makes it possible to disambiguate single line definitions when necessary.
Sep 17 2014
prev sibling parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Wednesday, 17 September 2014 at 16:32:04 UTC, Dicebot wrote:
 On Wednesday, 17 September 2014 at 10:00:31 UTC, Jack Applegame 
 wrote:
 You can use module name and line number as unique tag.
This is exactly what I would have expected as default behaviour. Is anyone aware why this counter appoach was used instead?
It's a deceivingly bad default. See the comments in the PR that introduced Typedef[1]. [1] https://github.com/D-Programming-Language/phobos/pull/300
Sep 18 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 19 September 2014 at 04:44:07 UTC, Jakob Ovrum wrote:
 On Wednesday, 17 September 2014 at 16:32:04 UTC, Dicebot wrote:
 On Wednesday, 17 September 2014 at 10:00:31 UTC, Jack 
 Applegame wrote:
 You can use module name and line number as unique tag.
This is exactly what I would have expected as default behaviour. Is anyone aware why this counter appoach was used instead?
It's a deceivingly bad default. See the comments in the PR that introduced Typedef[1]. [1] https://github.com/D-Programming-Language/phobos/pull/300
Yes, this is a problem. But how is that possibly worse than existing implementation which gives wrong results in 100% of cases? file/line cookie approach has issues but it is best we can get with existing language support.
Sep 19 2014
parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Friday, 19 September 2014 at 11:14:06 UTC, Dicebot wrote:
 On Friday, 19 September 2014 at 04:44:07 UTC, Jakob Ovrum wrote:
 On Wednesday, 17 September 2014 at 16:32:04 UTC, Dicebot wrote:
 On Wednesday, 17 September 2014 at 10:00:31 UTC, Jack 
 Applegame wrote:
 You can use module name and line number as unique tag.
This is exactly what I would have expected as default behaviour. Is anyone aware why this counter appoach was used instead?
It's a deceivingly bad default. See the comments in the PR that introduced Typedef[1]. [1] https://github.com/D-Programming-Language/phobos/pull/300
Yes, this is a problem. But how is that possibly worse than existing implementation which gives wrong results in 100% of cases? file/line cookie approach has issues but it is best we can get with existing language support.
`Typedef` clearly comes with a big caveat that isn't apparent from just reading user code. The documentation has to be read, and the documentation clearly states that the cookie parameter has to be used to get unique types. It's much less surprising to have it generate unique types only when explicitly given a cookie than having it sometimes make unique types and sometimes not depending on complex conditions. Maybe `Typedef` could be neatly fixed by making it a mixin template?
Sep 19 2014
prev sibling next sibling parent reply "Wyatt" <wyatt.epp gmail.com> writes:
On Wednesday, 17 September 2014 at 02:57:03 UTC, Freddy wrote:
 When you have separate 2 typedefs of the exact same type, they
 are equal.While this maybe able to be solved with
 Typedef!(Typedef!(...)) different modules typedef ing the same
 type (most likely build-in types) would have their typedef be
 equivalent thereby degrading the purpose of typedef.
 ---
 import std.typecons;

 alias meter = Typedef!float;
 alias feet = Typedef!float;
 static assert(!is(meter==feet));
 ---
 Your thoughts?
Reading this thread and thinking on it more... I acknowledge this is probably kind of naive, but it makes aliases feel not-very-useful to me. It doesn't give you type checking or function overloading because as far as the semantic pass is concerned, they're identical. And that's fine. The documentation on AliasDeclaration is kind of verbose, but it does clarify that at some point (had to reread it a couple times to notice, though...). So I get that aliasing is at least situationally useful (e.g. utility shortening), and I think it's been stated repeatedly that it's great for metaprogramming things, but the aggregate makes this situation suck. If you want those things to work, you have to wrap it in a struct and use alias this (which IS a legitimately cool application of the aliasing semantics, I'll grant). This can be mitigated somewhat, but it still feels inelegant and not-D-like for something I'd really like to use easily and often. Also, for the hardcore among you, I think your cache may hate you for this (I don't recall if that overhead gets optimised away). I think you could be forgiven for expecting std.typecons.Typedef to provide the alternative we need, but it ends up being only about as useful as typedef in C (or maybe a bit less?). Is there some better solution I've missed? (I wouldn't consider the cookie parameter a better solution; I would consider it a wart.) -Wyatt
Sep 18 2014
next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Thu, Sep 18, 2014 at 05:48:30PM +0000, Wyatt via Digitalmars-d wrote:
[...]
 If you want those things to work, you have to wrap it in a struct and
 use alias this (which IS a legitimately cool application of the
 aliasing semantics, I'll grant).  This can be mitigated somewhat, but
 it still feels inelegant and not-D-like for something I'd really like
 to use easily and often.  Also, for the hardcore among you, I think
 your cache may hate you for this (I don't recall if that overhead gets
 optimised away).
[...] Why would your cache hate you for it? A struct that contains, say, a single int, is at the assembly level identical to the int itself, because structs are value types and they were basically designed to be "glorified ints", as Andrei puts it in TDPL. When you write something like: struct S { int x; alias x this; // ... } S s; s++; basically "s++" gets translated to "s.x++", and since S behaves basically identically to an int, which means it should get enregistered under the same circumstances, the generated machine code should be identical to when you wrote "int" instead of "S". I don't see why this should have any effect on the cache. Unless you added extra fields to your struct where you shouldn't, and it becomes too big to fit in registers, then it's not really the compiler's fault. :-P The neatest thing about this, is that any operator overloading you implement for S will, in effect, behave like overloading the built-in int operators; and if your operator overloads have simple implementations, they will be inlined and you get basically a "native" int but with overloaded operators. (This, of course, is the whole point behind the 'checkedint' type currently used by some internal Phobos / dmd functions. You basically have a type that's identical to int in every way, except that some operations will have overflow checks inserted in front in the machine code.) This is why 'alias this' is such a total stroke of genius. It brings the parity between user and built-in types to a whole new level of cool. T -- Curiosity kills the cat. Moral: don't be the cat.
Sep 18 2014
parent "Wyatt" <wyatt.epp gmail.com> writes:
On Thursday, 18 September 2014 at 18:02:08 UTC, H. S. Teoh via 
Digitalmars-d wrote:
 basically "s++" gets translated to "s.x++", and since S behaves
 basically identically to an int, which means it should get
 enregistered under the same circumstances, the generated machine
 code should be identical to when you wrote "int" instead of "S".
Oh, neat. I stand corrected on that point. Thanks.
 I don't see why this should have any effect on the cache.
That's my mistake; I thought there was overhead for structs in D. Should have done my homework! It's too bad this does nothing for the usability issues. :/ -Wyatt
Sep 18 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/18/14, 10:48 AM, Wyatt wrote:
 (I wouldn't consider the cookie parameter a better solution; I would
 consider it a wart.)
That's the right solution. Andrei
Sep 18 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I 
 would consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart. Bye, bearophile
Sep 18 2014
next sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Fri, 19 Sep 2014 05:53:00 +0000
schrieb "bearophile" <bearophileHUGS lycos.com>:

 Andrei Alexandrescu:
 
 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I 
 would consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart. Bye, bearophile
We should probably revert to having real typedefs. I find myself not using Typedef either. Instead I use wrapper structs with alias this, because they fit the shoe much better by introducing a unique symbol in a straight forward way :) Rationale Typedef is not flexible enough to cover all use cases. This is better done with a language solution. -- Marco
Sep 18 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/18/14, 11:45 PM, Marco Leise wrote:
 Am Fri, 19 Sep 2014 05:53:00 +0000
 schrieb "bearophile" <bearophileHUGS lycos.com>:

 Andrei Alexandrescu:

 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I
 would consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart. Bye, bearophile
We should probably revert to having real typedefs.
Should not.
 I find myself not using Typedef either. Instead I use wrapper
 structs with alias this, because they fit the shoe much better
 by introducing a unique symbol in a straight forward way :)

 Rationale

 Typedef is not flexible enough to cover all use cases.
 This is better done with a language solution.
What's missing? Andrei
Sep 19 2014
parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Fri, 19 Sep 2014 08:02:30 -0700
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 9/18/14, 11:45 PM, Marco Leise wrote:
 We should probably revert to having real typedefs.
Should not.
Ok, but don't ask me to use alias ALfloat = std.typecons.Typedef!(float, "yummyCookie23"); when it could be typedef ALfloat = float; ! :)
 I find myself not using Typedef either. Instead I use wrapper
 structs with alias this, because they fit the shoe much better
 by introducing a unique symbol in a straight forward way :)

 Rationale

 Typedef is not flexible enough to cover all use cases.
 This is better done with a language solution.
What's missing? Andrei
That was more of a pun on the original deprecation rationale: "typedef is not flexible enough to cover all use cases. This is better done with a library solution." Frankly though it seems like templates are the improper tool to create new unique symbols when at the same time we more or less depend on templates only being instantiated once for the same arguments. -- Marco
Sep 19 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/19/14, 11:36 PM, Marco Leise wrote:
 Am Fri, 19 Sep 2014 08:02:30 -0700
 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 9/18/14, 11:45 PM, Marco Leise wrote:
 We should probably revert to having real typedefs.
Should not.
Ok, but don't ask me to use alias ALfloat = std.typecons.Typedef!(float, "yummyCookie23"); when it could be typedef ALfloat = float; ! :)
I think this is an entirely palatable idiom: alias ALfloat = std.typecons.Typedef!(float, "ALfloat"); Andrei
Sep 20 2014
next sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 20 Sep 2014 08:25:17 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 I think this is an entirely palatable idiom:
 alias ALfloat =3D std.typecons.Typedef!(float, "ALfloat");
this is ugly. even if we remove "std.typecons." it's still ugly. making such core feature ugly is the right way to marginalize it. "what? all this uglyness only for simple typedef? screw it, i'll go with simple `alias ALfloat =3D float;`! oh, wait... this gives me nothing and i already messed some declarations... ah, screw it, will use `float` then!" the whole thing with aliasing Typedef is broken. yes, it's smart to use library for this (see, our language is THAT powerful!), but it's uuugly. the same thing as with octal literals: we have 0b, we have 0x, yet it's very smart to banish octals to phobos and use octal!"660" instead of logical 0o660. phew. but i know: octal literals are handy, so they will never make their way to mainline. "typedef" construct is handy, so...
Sep 20 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
ketmar:

 but i know: octal literals are handy, so they will never make 
 their way to mainline. "typedef" construct is handy, so...
A well working Typedef/typedef (named "newtype" in Haskell, where it's a built-in) is more commonly useful than octal literals. Bye, bearophile
Sep 20 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 20 Sep 2014 16:36:49 +0000
bearophile via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 A well working Typedef/typedef (named "newtype" in Haskell, where=20
 it's a built-in) is more commonly useful than octal literals.
i'm not saying that octal literals are in much need, i'm talking about consistency (again).
Sep 20 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/20/14, 9:32 AM, ketmar via Digitalmars-d wrote:
 On Sat, 20 Sep 2014 08:25:17 -0700
 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
 wrote:

 I think this is an entirely palatable idiom:
 alias ALfloat = std.typecons.Typedef!(float, "ALfloat");
this is ugly.
But not unusable.
 even if we remove "std.typecons." it's still ugly. making
 such core feature ugly is the right way to marginalize it. "what? all
 this uglyness only for simple typedef? screw it, i'll go with simple
 `alias ALfloat = float;`! oh, wait... this gives me nothing and i
 already messed some declarations... ah, screw it, will use `float`
 then!"
Are you saying you're giving up on an entire design because you can't bring yourself to type one string?
 the whole thing with aliasing Typedef is broken.
s/broken/less convenient than a builtin/ and we agree.
 yes, it's smart to use
 library for this (see, our language is THAT powerful!), but it's uuugly.
uuugly != broken
 the same thing as with octal literals: we have 0b, we have 0x, yet it's
 very smart to banish octals to phobos and use octal!"660" instead of
 logical 0o660. phew.

 but i know: octal literals are handy, so they will never make their way
 to mainline. "typedef" construct is handy, so...
Not sure I understand this last point. At any rate, if your entire line of reasoning hinges on you being unwilling to type a few more characters to have a workable solution, I have difficulty taking it seriously. Andrei
Sep 20 2014
next sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 20 Sep 2014 10:20:28 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 I think this is an entirely palatable idiom:
 alias ALfloat =3D std.typecons.Typedef!(float, "ALfloat");
this is ugly.
But not unusable.
tying code using my nose is entirely possible too, and it even fun. but it's far from being "usable technique".
 Are you saying you're giving up on an entire design because you can't=20
 bring yourself to type one string?
not just one string. people will use ugly features only when they are forced to. D makes using typedefs unnecessarily ugly, thus marginalising them. turn struct declaration to "Declare!struct" and leave class declaration as-is, and people will start use classes instead of structs, even when struct is better fit. or remove "string" alias. what i'm trying to say is that "typedef" is "core feature" if we are talking about type safety, and it should be nice or people will not use it. current "Typedef" is not nice.
 the whole thing with aliasing Typedef is broken.
s/broken/less convenient than a builtin/ and we agree.
no, it is broken. for such important feature "less convient" means "broken".
 uuugly !=3D broken
"=3D=3D" for this case.
 Not sure I understand this last point. At any rate, if your entire
 line of reasoning hinges on you being unwilling to type a few more
 characters to have a workable solution, I have difficulty taking it
 seriously.
i don't want "workable solution", i want "usable solution". "Typedef" is barely usable due to being one of fundamental features and uuugly. make something ugly and people will avoid it as much as they can. if we don't care about compile-time type safety... ok, let it stay ugly.
Sep 20 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/20/14, 10:49 AM, ketmar via Digitalmars-d wrote:
 i don't want "workable solution", i want "usable solution".
Guess a copyediting pass would have caught that one. -- Andrei
Sep 20 2014
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Saturday, 20 September 2014 at 17:20:28 UTC, Andrei 
Alexandrescu wrote:
 On 9/20/14, 9:32 AM, ketmar via Digitalmars-d wrote:
 On Sat, 20 Sep 2014 08:25:17 -0700
 Andrei Alexandrescu via Digitalmars-d 
 <digitalmars-d puremagic.com>
 wrote:

 I think this is an entirely palatable idiom:
 alias ALfloat = std.typecons.Typedef!(float, "ALfloat");
this is ugly.
But not unusable.
Requiring manual tracing of identity = unusable. With my proposed implementation it is at least clear when it is going to fail. This is much worse: module a; alias Int1 = Typedef!(int, "MyInt"); module b; alias Int2 = Typedef!(int, "MyInt"); // oh I didn't know someone else used that cookie too.. static assert (is(Int1 == Int2)); Such solution simply can't be allowed in any project with >1 active programmer unless either type safety is not important or some additional restrictions on adding new typedefs are added process-wise (insane).
Sep 21 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 module a;

 alias Int1 = Typedef!(int, "MyInt");

 module b;

 alias Int2 = Typedef!(int, "MyInt");

 // oh I didn't know someone else used that cookie too..
Sooner or later a dirty semantics will bite your ass. It's an important rule of language/library design.
 unless either type safety is not important
If type safety is not so important in a piece of code, you probably are already not using a typedef/Typedef/newtype. Bye, bearophile
Sep 21 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 7:49 AM, bearophile wrote:
 Dicebot:

 module a;

 alias Int1 = Typedef!(int, "MyInt");

 module b;

 alias Int2 = Typedef!(int, "MyInt");

 // oh I didn't know someone else used that cookie too..
Sooner or later a dirty semantics will bite your ass.
Mine ain't hurting. -- Andrei
Sep 21 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 7:22 AM, Dicebot wrote:
 On Saturday, 20 September 2014 at 17:20:28 UTC, Andrei Alexandrescu wrote:
 On 9/20/14, 9:32 AM, ketmar via Digitalmars-d wrote:
 On Sat, 20 Sep 2014 08:25:17 -0700
 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
 wrote:

 I think this is an entirely palatable idiom:
 alias ALfloat = std.typecons.Typedef!(float, "ALfloat");
this is ugly.
But not unusable.
Requiring manual tracing of identity = unusable. With my proposed implementation it is at least clear when it is going to fail. This is much worse: module a; alias Int1 = Typedef!(int, "MyInt");
alias Int1 = Typedef!(int, "a.Int1");
 module b;

 alias Int2 = Typedef!(int, "MyInt");
alias Int2 = Typedef!(int, "b.Int2");
 // oh I didn't know someone else used that cookie too..
 static assert (is(Int1 == Int2));

 Such solution simply can't be allowed in any project with >1 active
 programmer unless either type safety is not important or some additional
 restrictions on adding new typedefs are added process-wise (insane).
More hyperbole won't help the weakness of the argument. Andrei
Sep 21 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Sunday, 21 September 2014 at 15:15:27 UTC, Andrei Alexandrescu 
wrote:
 alias Int2 = Typedef!(int, "b.Int2");
..and don't forget to keep those updated when module / aggregate names change via refactoring! Sorry but what you pretend to be a pragmatical solution is just a useless crap I am not going to ever use while I am in sane mind. Especially considering that more reliable alternative can be hacked in few minutes.
 More hyperbole won't help the weakness of the argument.
Calling daily concerns of others "hyperbole" doesn't help to sell your solution as well-thought and reasonable.
Sep 21 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 8:28 AM, Dicebot wrote:
 On Sunday, 21 September 2014 at 15:15:27 UTC, Andrei Alexandrescu wrote:
 alias Int2 = Typedef!(int, "b.Int2");
...and don't forget to keep those updated when module / aggregate names change via refactoring!
alias Int2 = Typedef!(int, __MODULE__ ~ ".Int2");
 Sorry but what you pretend to be a pragmatical solution is just a
 useless crap I  am not going to ever use while I am in sane mind.
 Especially considering that more reliable alternative can be hacked in
 few minutes.

 More hyperbole won't help the weakness of the argument.
Calling daily concerns of others "hyperbole" doesn't help to sell your solution as well-thought and reasonable.
Got it. So that's what people say when they run out of arguments. Andrei
Sep 21 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Sunday, 21 September 2014 at 18:09:00 UTC, Andrei Alexandrescu
wrote:
 On 9/21/14, 8:28 AM, Dicebot wrote:
 On Sunday, 21 September 2014 at 15:15:27 UTC, Andrei 
 Alexandrescu wrote:
 alias Int2 = Typedef!(int, "b.Int2");
...and don't forget to keep those updated when module / aggregate names change via refactoring!
alias Int2 = Typedef!(int, __MODULE__ ~ ".Int2");
Yeah now let's add __LINE__ there to make sure no clashes happen and suddenly we get the same solution as the one proposed but with manual typing of all special symbols. This is definitely one of most convincing set of arguments I have ever seen from you in this NG. Not.
Sep 21 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 12:05 PM, Dicebot wrote:
 On Sunday, 21 September 2014 at 18:09:00 UTC, Andrei Alexandrescu
 wrote:
 On 9/21/14, 8:28 AM, Dicebot wrote:
 On Sunday, 21 September 2014 at 15:15:27 UTC, Andrei Alexandrescu wrote:
 alias Int2 = Typedef!(int, "b.Int2");
...and don't forget to keep those updated when module / aggregate names change via refactoring!
alias Int2 = Typedef!(int, __MODULE__ ~ ".Int2");
Yeah now let's add __LINE__ there to make sure no clashes happen and suddenly we get the same solution as the one proposed but with manual typing of all special symbols.
No need. -- Andrei
Sep 21 2014
prev sibling next sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 21 Sep 2014 08:15:29 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 alias Int1 =3D Typedef!(int, "a.Int1");
 alias Int2 =3D Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Sep 21 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 8:29 AM, ketmar via Digitalmars-d wrote:
 On Sun, 21 Sep 2014 08:15:29 -0700
 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
 wrote:

 alias Int1 = Typedef!(int, "a.Int1");
 alias Int2 = Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Use __MODULE__. -- Andrei
Sep 21 2014
next sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 21 Sep 2014 11:09:28 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 alias Int1 =3D Typedef!(int, "a.Int1");
 alias Int2 =3D Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Use __MODULE__. -- Andrei
you still can't grok concept of "ugly =3D=3D unusable". thank you, i'd better fsck this miserably attempt on type security, and many other practical programmers too. we trying to explain you this and each time you answers "so what? no, it's not." even to people who tried to use this disgusting "solution" and found it unacceptable and broken. alias Int1 =3D Typedef!(int, __MODULE__~".Int1"); don't make me laugh. this is not just ugly, this is MEGAUGLY. then we can make some kind of magic template to hide this uglyness, yes. the uglyness which shouldn't be there in the first place. each time when such ugly "workaround" proposed we can see the feature as completely broken. people trying to tell you that it is broken for single developer (too much to type for nothing). that it is broken for group developement (people will forget to mix all the uglyness for necessary result). that it is just broken. please, we aren't bunch of kids who just happen to dislike typing extra chars. our objections backed by trying to use the feature in practice.
Sep 21 2014
next sibling parent reply "Tourist" <gravatar gravatar.com> writes:
On Sunday, 21 September 2014 at 20:41:22 UTC, ketmar via
Digitalmars-d wrote:
 On Sun, 21 Sep 2014 11:09:28 -0700
 Andrei Alexandrescu via Digitalmars-d 
 <digitalmars-d puremagic.com>
 wrote:

 alias Int1 = Typedef!(int, "a.Int1");
 alias Int2 = Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Use __MODULE__. -- Andrei
you still can't grok concept of "ugly == unusable". thank you, i'd better fsck this miserably attempt on type security, and many other practical programmers too. we trying to explain you this and each time you answers "so what? no, it's not." even to people who tried to use this disgusting "solution" and found it unacceptable and broken. alias Int1 = Typedef!(int, __MODULE__~".Int1"); don't make me laugh. this is not just ugly, this is MEGAUGLY. then we can make some kind of magic template to hide this uglyness, yes. the uglyness which shouldn't be there in the first place. each time when such ugly "workaround" proposed we can see the feature as completely broken. people trying to tell you that it is broken for single developer (too much to type for nothing). that it is broken for group developement (people will forget to mix all the uglyness for necessary result). that it is just broken. please, we aren't bunch of kids who just happen to dislike typing extra chars. our objections backed by trying to use the feature in practice.
Why don't you capitalize? Looks like you're a reasonable person, and this makes an outsider think that your IQ is lower than the average. IMO.
Sep 21 2014
next sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 21 Sep 2014 20:48:34 +0000
Tourist via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Why don't you capitalize?
it's my "one man's crusade" against the thing i see as completely useless.
 Looks like you're a reasonable person, and this makes an outsider
 think that your IQ is lower than the average. IMO.
and my English is bad too (mea culpa; i have to fix it by taking some courses). but i believe that arguments aren't depend of the speaker. and i don't care what people think about my personality. if they choose to ignore everything i'm writing just 'cause they think that i'm dumb... ah, so be it. it's arguments that counts, not their source.
Sep 21 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 2:32 PM, ketmar via Digitalmars-d wrote:
 On Sun, 21 Sep 2014 20:48:34 +0000
 Tourist via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Why don't you capitalize?
it's my "one man's crusade" against the thing i see as completely useless.
 Looks like you're a reasonable person, and this makes an outsider
 think that your IQ is lower than the average. IMO.
and my English is bad too (mea culpa; i have to fix it by taking some courses). but i believe that arguments aren't depend of the speaker. and i don't care what people think about my personality. if they choose to ignore everything i'm writing just 'cause they think that i'm dumb... ah, so be it. it's arguments that counts, not their source.
I don't mind the capitalization, ad hominem, etc. The arguments against Typedef are honestly terrible (by all participants), and the attempts at enhancing them through hyperbole are embarrassing. -- Andrei
Sep 21 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 21 Sep 2014 15:22:05 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 I don't mind the capitalization, ad hominem, etc. The arguments
 against Typedef are honestly terrible (by all participants), and the
 attempts at enhancing them through hyperbole are embarrassing. --
 Andrei
this discussion raises some heat, methinks. we all should take some rest and calm down. sorry for beung rude and so on. nothing personal. ;-)
Sep 21 2014
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Tourist:

 Why don't you capitalize?
 Looks like you're a reasonable person, and this makes an 
 outsider think that your IQ is lower than the average. IMO.
IQs are a flawed unit of measure. ketmar intelligences seem fine. ketmar reasoning is good here. Why don't you redirect your efforts against someone else more deserving? Bye, bearophile
Sep 21 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 1:41 PM, ketmar via Digitalmars-d wrote:
 On Sun, 21 Sep 2014 11:09:28 -0700
 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
 wrote:

 alias Int1 = Typedef!(int, "a.Int1");
 alias Int2 = Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Use __MODULE__. -- Andrei
you still can't grok concept of "ugly == unusable".
Also I must be missing the distinction between "workable solution" and "usable solution". Such semantic subtleties seem to be lost on me in this context.
 thank you, i'd
 better fsck this miserably attempt on type security, and many other
 practical programmers too. we trying to explain you this and each time
 you answers "so what? no, it's not." even to people who tried to use
 this disgusting "solution" and found it unacceptable and broken.
The problem here is inept argumentation. I'm all for a well argued debate. This argument seems to have trouble getting legs, and foaming at the mouth is unlikely to add value to it.
 alias Int1 = Typedef!(int, __MODULE__~".Int1");

 don't make me laugh. this is not just ugly, this is MEGAUGLY.
Pretty much by what I mean with "foaming at the mouth" and "vivid anecdote fallacy". Can you make an argument with words in the dictionary?
 then we
 can make some kind of magic template to hide this uglyness, yes. the
 uglyness which shouldn't be there in the first place. each time when
 such ugly "workaround" proposed we can see the feature as completely
 broken.

 people trying to tell you that it is broken for single developer (too
 much to type for nothing). that it is broken for group developement
 (people will forget to mix all the uglyness for necessary result). that
 it is just broken.

 please, we aren't bunch of kids who just happen to dislike typing extra
 chars. our objections backed by trying to use the feature in practice.
I'm not buying this. The more it goes the less convincing it goes. Andrei
Sep 21 2014
next sibling parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 21 Sep 2014 15:17:52 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 I'm not buying this. The more it goes the less convincing it goes.
oh. i'm off, i just don't know what else to say. this discussion seems to go in circles, so it's better to put it on hold for some time. at least until someone invents better arguments. ;-)
Sep 21 2014
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/22/2014 12:17 AM, Andrei Alexandrescu wrote:
 "vivid anecdote fallacy"
FWIW: https://www.google.ch/?gws_rd=cr&ei=XVYfVIu7IcL1OYi7gMgH#q=%22vivid+anecdote+fallacy%22
Sep 21 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 3:52 PM, Timon Gehr wrote:
 On 09/22/2014 12:17 AM, Andrei Alexandrescu wrote:
 "vivid anecdote fallacy"
FWIW: https://www.google.ch/?gws_rd=cr&ei=XVYfVIu7IcL1OYi7gMgH#q=%22vivid+anecdote+fallacy%22
Pretty awesome :o). I was referring to "misleading vividness:" http://en.wikipedia.org/wiki/Misleading_vividness - which shows up once in a while in this forum... -- Andrei
Sep 21 2014
prev sibling parent reply "Don" <x nospam.com> writes:
On Sunday, 21 September 2014 at 18:09:26 UTC, Andrei Alexandrescu 
wrote:
 On 9/21/14, 8:29 AM, ketmar via Digitalmars-d wrote:
 On Sun, 21 Sep 2014 08:15:29 -0700
 Andrei Alexandrescu via Digitalmars-d 
 <digitalmars-d puremagic.com>
 wrote:

 alias Int1 = Typedef!(int, "a.Int1");
 alias Int2 = Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Use __MODULE__. -- Andrei
Yes, but you're advocating a hack. The original premise does seem to be correct: library Typedefs are fundamentally broken. The semantics of templates does not match what one expects from a typedef: ie, declaring a new, unique type. If you have to pass __MODULE__ in, it's not really a library solution. The user code needs to pass in a nasty implementation detail in order to get a unique type. And it does seem to me, that because it isn't possible to do a proper library typedef, you've attempted to redefine what a Typedef is supposed to do. And sure, it you remove the requirement to create a unique type, Typedef isn't broken. But then it isn't very useful, either. You can't, for example, use it to define the various Windows HANDLEs (HMENU, etc), which was one of the most successful use cases for D1's typedef. Having said that, though, the success of 'alias this' does raise some interesting questions about how useful the concept of a typedef is. Certainly it's much less useful than when Typedef was created. My feeling is that almost every time when you want to create a new type from an existing one, you actually want to restrict the operations which can be performed on it. (Eg if you have typedef money = double; then money*money doesn't make much sense). For most typedefs I think you're better off with 'alias this'.
Sep 22 2014
next sibling parent "Meta" <jared771 gmail.com> writes:
On Monday, 22 September 2014 at 09:39:29 UTC, Don wrote:
 My feeling is that almost every time when you want to create a 
 new type from an existing one, you actually want to restrict 
 the operations which can be performed on it. (Eg if you have  
 typedef money = double; then money*money doesn't make much 
 sense). For most typedefs I think you're better off with 'alias 
 this'.
`alias this` doesn't restrict what operations can be performed on the supertype. struct Money { this(double d) { amount = d; } double amount; alias amount this; } void main() { //This doesn't compile without a constructor defined //that takes a double... I thought alias this took //care of that, but apparently not Money m = 2.0; Money n = m * m; assert(n == 4.0); }
Sep 22 2014
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/22/14, 2:39 AM, Don wrote:
 On Sunday, 21 September 2014 at 18:09:26 UTC, Andrei Alexandrescu wrote:
 On 9/21/14, 8:29 AM, ketmar via Digitalmars-d wrote:
 On Sun, 21 Sep 2014 08:15:29 -0700
 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
 wrote:

 alias Int1 = Typedef!(int, "a.Int1");
 alias Int2 = Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Use __MODULE__. -- Andrei
Yes, but you're advocating a hack.
Oh but I very much disagree.
 The original premise does seem to be
 correct: library Typedefs are fundamentally broken. The semantics of
 templates does not match what one expects from a typedef: ie, declaring
 a new, unique type.

 If you have to pass __MODULE__ in, it's not really a library solution.
 The user code needs to pass in a nasty implementation detail in order to
 get a unique type.
How many libraries did you use that came with no idioms for their usage?
 And it does seem to me, that because it isn't possible to do a proper
 library typedef, you've attempted to redefine what a Typedef is supposed
 to do. And sure, it you remove the requirement to create a unique type,
 Typedef isn't broken.
You're two paragraphs away from "library Typedefs are fundamentally broken". Now which one is it?
 But then it isn't very useful, either. You can't,
 for example, use it to define the various Windows HANDLEs (HMENU, etc),
 which was one of the most successful use cases for D1's typedef.
alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU"); So please s/can't/can't the same exact way built-in typedef would have done it/.
 Having said that, though, the success of 'alias this' does raise some
 interesting questions about how useful the concept of a typedef is.
 Certainly it's much less useful than when Typedef was created.

 My feeling is that almost every time when you want to create a new type
 from an existing one, you actually want to restrict the operations which
 can be performed on it. (Eg if you have  typedef money = double; then
 money*money doesn't make much sense). For most typedefs I think you're
 better off with 'alias this'.
When control is needed, yah. I had some thoughts on adding policies to Typedef (convert to base type etc) but as it seems it's already unusable, I won't bring them up :o). Andrei
Sep 22 2014
parent reply "Don" <x nospam.com> writes:
On Monday, 22 September 2014 at 14:56:26 UTC, Andrei Alexandrescu 
wrote:
 On 9/22/14, 2:39 AM, Don wrote:
 On Sunday, 21 September 2014 at 18:09:26 UTC, Andrei 
 Alexandrescu wrote:
 On 9/21/14, 8:29 AM, ketmar via Digitalmars-d wrote:
 On Sun, 21 Sep 2014 08:15:29 -0700
 Andrei Alexandrescu via Digitalmars-d 
 <digitalmars-d puremagic.com>
 wrote:

 alias Int1 = Typedef!(int, "a.Int1");
 alias Int2 = Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
Use __MODULE__. -- Andrei
Yes, but you're advocating a hack.
Oh but I very much disagree.
Now you are scaring me. It worries me that this kind of "solution" can be viewed as acceptable. It's the kind of hacky code I left C++ to escape from. People in this thread said it was "ugly" and you dismissed that. But this isn't just a matter of personal aesthetics. If you want something objective, it's not DRY, and it's verbose in a non-trivial way. The hacky design leads to error-prone code. eg you can easily get a copy-paste bug because it's not DRY. alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU"); alias HFONT = Typedef!(void*, __MODULE__ ~ ".HMENU"); // oops
 The original premise does seem to be
 correct: library Typedefs are fundamentally broken. The 
 semantics of
 templates does not match what one expects from a typedef: ie, 
 declaring
 a new, unique type.

 If you have to pass __MODULE__ in, it's not really a library 
 solution.
 The user code needs to pass in a nasty implementation detail 
 in order to
 get a unique type.
How many libraries did you use that came with no idioms for their usage?
Describing this as an "idiom" is extremely generous. My standards are higher.
 And it does seem to me, that because it isn't possible to do a 
 proper
 library typedef, you've attempted to redefine what a Typedef 
 is supposed
 to do. And sure, it you remove the requirement to create a 
 unique type,
 Typedef isn't broken.
You're two paragraphs away from "library Typedefs are fundamentally broken". Now which one is it?
Phobos' Typedef is fundamentally broken, and that your claim that it is not, relies on moving the goalposts.
 But then it isn't very useful, either. You can't,
 for example, use it to define the various Windows HANDLEs 
 (HMENU, etc),
 which was one of the most successful use cases for D1's 
 typedef.
alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU"); So please s/can't/can't the same exact way built-in typedef would have done it/.
No. You can hammer nails in using a rock, but I'm not prepared to accept a rock as a kind of hammer. It's not a tool that belongs in any toolbox. My assertion is, there are no use cases for Phobos's Typedef. You're always better off doing something else.
Sep 23 2014
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 7:43 AM, Don wrote:
 On Monday, 22 September 2014 at 14:56:26 UTC, Andrei Alexandrescu wrote:
 On 9/22/14, 2:39 AM, Don wrote:
 Yes, but you're advocating a hack.
Oh but I very much disagree.
Now you are scaring me. It worries me that this kind of "solution" can be viewed as acceptable. It's the kind of hacky code I left C++ to escape from.
Hmm... doesn't strike me as similar to C++-specific hacks, but I understand the sentiment.
 People in this thread said it was "ugly" and you dismissed that.
Nononononono. I totally agree some may find it ugly! It's "unusable" I have a problem with.
 But
 this isn't just a matter of personal aesthetics.
 If you want something objective, it's not DRY, and it's verbose in a
 non-trivial way. The hacky design leads to error-prone code.
 eg you can easily get a copy-paste bug because it's not DRY.

 alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU");
 alias HFONT = Typedef!(void*, __MODULE__ ~ ".HMENU"); // oops
mixin(makeTypedef!("HMENU", void*)); mixin(makeTypedef!("HFONT", void*)); I said and I repeat: I do agree it's less convenient than a baked-in facility. Even with the proper default arguments and all. But I stand by Typedef as an adequate abstraction.
 How many libraries did you use that came with no idioms for their usage?
Describing this as an "idiom" is extremely generous. My standards are higher.
Well "extremely generous" is not "deluded" so I'll take that :o).
 And it does seem to me, that because it isn't possible to do a proper
 library typedef, you've attempted to redefine what a Typedef is supposed
 to do. And sure, it you remove the requirement to create a unique type,
 Typedef isn't broken.
You're two paragraphs away from "library Typedefs are fundamentally broken". Now which one is it?
Phobos' Typedef is fundamentally broken, and that your claim that it is not, relies on moving the goalposts.
I disagree. I'm not one to dismiss good arguments. But there aren't many here. There's gotta be a point at which you'll agree the whole argument against Typedef has no legs. It's working as designed (I forgot who designed it), the design fits the purpose, the semantics never surprised me, and when people now come with the pitchforks that it's broken, all I can do is send them to the manual. IT WORKS.
 But then it isn't very useful, either. You can't,
 for example, use it to define the various Windows HANDLEs (HMENU, etc),
 which was one of the most successful use cases for D1's typedef.
alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU"); So please s/can't/can't the same exact way built-in typedef would have done it/.
No. You can hammer nails in using a rock, but I'm not prepared to accept a rock as a kind of hammer. It's not a tool that belongs in any toolbox. My assertion is, there are no use cases for Phobos's Typedef. You're always better off doing something else.
But your evidence destroys your own assertion. Let me explain. You bring the typo example as the smoking gun. So I take it it's a biggie that, if fixed, would make you happy. But there are a number of trivial fixes to it, such as my defineTypedef above. So it looks like (a) Typedef can be used as long as you are careful to not type the wrong name, (b) with only trivial work, Typedef can be used without even the slightest repetition. So how come Typedef is unusable when it's usable by your own testimony? Andrei
Sep 23 2014
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 23 September 2014 at 16:01:35 UTC, Andrei 
Alexandrescu wrote:
 mixin(makeTypedef!("HMENU", void*));
struct HMENU { void* _; alias _ this; } Don't even have to import a Phobos module for it!
Sep 23 2014
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 9:15 AM, Adam D. Ruppe wrote:
 On Tuesday, 23 September 2014 at 16:01:35 UTC, Andrei Alexandrescu wrote:
 mixin(makeTypedef!("HMENU", void*));
struct HMENU { void* _; alias _ this; } Don't even have to import a Phobos module for it!
Even better. I love good idioms! -- Andrei
Sep 23 2014
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, Sep 23, 2014 at 09:26:51AM -0700, Andrei Alexandrescu via Digitalmars-d
wrote:
 On 9/23/14, 9:15 AM, Adam D. Ruppe wrote:
On Tuesday, 23 September 2014 at 16:01:35 UTC, Andrei Alexandrescu wrote:
mixin(makeTypedef!("HMENU", void*));
struct HMENU { void* _; alias _ this; } Don't even have to import a Phobos module for it!
Even better. I love good idioms! -- Andrei
To me, this is a big reason for Typedef being of little use. It's just so easy to use struct + alias this to achieve what you want (and to do so without tricky issues or hacks like counters or whatnot, plus you get to control exactly how it should behave without bothering with template parameters -- you can even do things like overload operators / methods, that Typedef can't do), that I find myself wondering what Typedef is actually good for, if anything! T -- Talk is cheap. Whining is actually free. -- Lars Wirzenius
Sep 23 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 9:37 AM, H. S. Teoh via Digitalmars-d wrote:
 On Tue, Sep 23, 2014 at 09:26:51AM -0700, Andrei Alexandrescu via
Digitalmars-d wrote:
 On 9/23/14, 9:15 AM, Adam D. Ruppe wrote:
 On Tuesday, 23 September 2014 at 16:01:35 UTC, Andrei Alexandrescu wrote:
 mixin(makeTypedef!("HMENU", void*));
struct HMENU { void* _; alias _ this; } Don't even have to import a Phobos module for it!
Even better. I love good idioms! -- Andrei
To me, this is a big reason for Typedef being of little use. It's just so easy to use struct + alias this to achieve what you want (and to do so without tricky issues or hacks like counters or whatnot, plus you get to control exactly how it should behave without bothering with template parameters -- you can even do things like overload operators / methods, that Typedef can't do), that I find myself wondering what Typedef is actually good for, if anything!
If language progress has gotten to the point where Typedef is obsolete (I recall there were a bunch of issues with alias this at the time we introduced Typedef), so much the better. I'm totally fine with "Typedef is obsolete". It's the poetic injustice of "Typedef is broken/unusable" I have a problem with. -- Andrei
Sep 23 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 It's the poetic injustice of "Typedef is broken/unusable" I
 have a problem with. -- Andrei
You seem the only one with such problem :-) Bye, bearophile
Sep 23 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 9:44 AM, bearophile wrote:
 Andrei Alexandrescu:

 It's the poetic injustice of "Typedef is broken/unusable" I
 have a problem with. -- Andrei
You seem the only one with such problem :-)
Argumentum ad populum again? You really are out of points to make. -- Andrei
Sep 23 2014
prev sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 23 Sep 2014 16:15:19 +0000
"Adam D. Ruppe via Digitalmars-d" <digitalmars-d puremagic.com> wrote:

 struct HMENU { void* _; alias _ this; }
=20
 Don't even have to import a Phobos module for it!
remember my "uuugly" on Typedef! and __MODULE__? well, i was wrong, it was just "ugly". and now i found really uuugly thing. please, even long Typedef! stinks less than this poor uuugly thing.
Sep 23 2014
parent reply simendsjo <simendsjo+dlang gmail.com> writes:
On 09/23/2014 08:05 PM, ketmar via Digitalmars-d wrote:
 On Tue, 23 Sep 2014 16:15:19 +0000
 "Adam D. Ruppe via Digitalmars-d" <digitalmars-d puremagic.com> wrote:
 
 struct HMENU { void* _; alias _ this; }

 Don't even have to import a Phobos module for it!
remember my "uuugly" on Typedef! and __MODULE__? well, i was wrong, it was just "ugly". and now i found really uuugly thing. please, even long Typedef! stinks less than this poor uuugly thing.
I disagree and think this code is idiomatic - it only uses regular features. If you mean `_`, that usually means "I don't care" or "Anything". But looking at Typedef!, it uses Proxy! rather than just alias. Haven't dived into Proxy, so the semantics might be quite different, perhaps subtly.
Sep 23 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 23 Sep 2014 21:22:43 +0200
simendsjo via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 I disagree and think this code is idiomatic
i'm not saying that it's not idiomatic. but it stil uuugly. this is exact uglyness that built-in "typedef" can hide. and a perfect fit for AST macro. ;-)
Sep 23 2014
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/23/2014 06:01 PM, Andrei Alexandrescu wrote:
 alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU");
 alias HFONT = Typedef!(void*, __MODULE__ ~ ".HMENU"); // oops
mixin(makeTypedef!("HMENU", void*)); mixin(makeTypedef!("HFONT", void*)); I said and I repeat: I do agree it's less convenient than a baked-in facility. Even with the proper default arguments and all. ...
But at that point, why not mix in an entire struct declaration? We even get better error messages out of this: module a.b.c; mixin MakeTypedef!("HMENU",void*)); mixin(makeTypedef!("HFONT",void*)); void main(){ HMENU hm; HFONT hf; hf=hm; } The error message will mention types 'HMENU' and 'Typedef!(void*,"a.b.c.HFONT")'. Furthermore, types will be distinct because the module system understands that they are distinct declarations.
Sep 23 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 3:58 PM, Timon Gehr wrote:
 On 09/23/2014 06:01 PM, Andrei Alexandrescu wrote:
 alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU");
 alias HFONT = Typedef!(void*, __MODULE__ ~ ".HMENU"); // oops
mixin(makeTypedef!("HMENU", void*)); mixin(makeTypedef!("HFONT", void*)); I said and I repeat: I do agree it's less convenient than a baked-in facility. Even with the proper default arguments and all. ...
But at that point, why not mix in an entire struct declaration?
That's fine too! I'm all for effective software development! -- Andrei
Sep 23 2014
prev sibling parent "Don" <x nospam.com> writes:
On Tuesday, 23 September 2014 at 16:01:35 UTC, Andrei 
Alexandrescu wrote:
 On 9/23/14, 7:43 AM, Don wrote:
 On Monday, 22 September 2014 at 14:56:26 UTC, Andrei 
 Alexandrescu wrote:
 On 9/22/14, 2:39 AM, Don wrote:
 Yes, but you're advocating a hack.
Oh but I very much disagree.
Now you are scaring me. It worries me that this kind of "solution" can be viewed as acceptable. It's the kind of hacky code I left C++ to escape from.
Hmm... doesn't strike me as similar to C++-specific hacks, but I understand the sentiment.
 People in this thread said it was "ugly" and you dismissed 
 that.
Nononononono. I totally agree some may find it ugly! It's "unusable" I have a problem with.
I think that "unusable" has been used with two meanings in this thread. That's why I've been using the word "hack".
 But
 this isn't just a matter of personal aesthetics.
 If you want something objective, it's not DRY, and it's 
 verbose in a
 non-trivial way. The hacky design leads to error-prone code.
 eg you can easily get a copy-paste bug because it's not DRY.

 alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU");
 alias HFONT = Typedef!(void*, __MODULE__ ~ ".HMENU"); // oops
mixin(makeTypedef!("HMENU", void*)); mixin(makeTypedef!("HFONT", void*)); I said and I repeat: I do agree it's less convenient than a baked-in facility. Even with the proper default arguments and all. But I stand by Typedef as an adequate abstraction.
You need a very, very good reason to require a string mixin in user code. I'm not seeing that here. The cure is worse than the disease.
 How many libraries did you use that came with no idioms for 
 their usage?
Describing this as an "idiom" is extremely generous. My standards are higher.
Well "extremely generous" is not "deluded" so I'll take that :o).
 And it does seem to me, that because it isn't possible to do 
 a proper
 library typedef, you've attempted to redefine what a Typedef 
 is supposed
 to do. And sure, it you remove the requirement to create a 
 unique type,
 Typedef isn't broken.
You're two paragraphs away from "library Typedefs are fundamentally broken". Now which one is it?
Phobos' Typedef is fundamentally broken, and that your claim that it is not, relies on moving the goalposts.
I disagree. I'm not one to dismiss good arguments. But there aren't many here. There's gotta be a point at which you'll agree the whole argument against Typedef has no legs. It's working as designed (I forgot who designed it), the design fits the purpose, the semantics never surprised me, and when people now come with the pitchforks that it's broken, all I can do is send them to the manual. IT WORKS.
The argument is that if you use Typedef for real-world use cases, your code is broken unless you use an unintuitive hack. The OP was proof that this is actually happening. I think your starting point is wrong. The design does *not* fit the purpose. We got Typedef to appease objections to 'typedef' being removed from the language. And it did had the effect of silencing the critics. We all expected Typedef to be a drop-in replacement for typedef, not something with dangerously different semantics. Now, if, right from the beginning, you never expected Typedef to replace typedef, then I can see why you think that Typedef is not broken. (But in that case I have no idea what you thought Typedef would be used for). Typedef solves the wrong problem, and solves it well. But when you try to use it to solve the right problem, you have to use an unintuitive hack.
 But then it isn't very useful, either. You can't,
 for example, use it to define the various Windows HANDLEs 
 (HMENU, etc),
 which was one of the most successful use cases for D1's 
 typedef.
alias HMENU = Typedef!(void*, __MODULE__ ~ ".HMENU"); So please s/can't/can't the same exact way built-in typedef would have done it/.
No. You can hammer nails in using a rock, but I'm not prepared to accept a rock as a kind of hammer. It's not a tool that belongs in any toolbox. My assertion is, there are no use cases for Phobos's Typedef. You're always better off doing something else.
But your evidence destroys your own assertion. Let me explain. You bring the typo example as the smoking gun. So I take it it's a biggie that, if fixed, would make you happy.
Not really. I showed that example simply to illustrate that the complaint "this is ugly" is more than an personal preference. It's ugly because it's a hack.
 But there are a number of trivial fixes to it, such as my 
 defineTypedef above. So it looks like (a) Typedef can be used 
 as long as you are careful to not type the wrong name, (b) with 
 only trivial work, Typedef can be used without even the 
 slightest repetition.

 So how come Typedef is unusable when it's usable by your own 
 testimony?
I have never said it couldn't be used. I said that it's usable, in the same way that a rock is usable as a hammer. As a substitute for a built-in typedef, it's not a library solution, it's a library-supported hack. And we should remove it before it leads more people astray.
Sep 24 2014
prev sibling parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 23 Sep 2014 14:43:40 +0000
Don via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Phobos' Typedef is fundamentally broken, and that your claim that=20
 it is not, relies on moving the goalposts.
actually, it's not. i grok Andrei's POV and he is perfectly right in what he is saying. not that i agreed with his POV, though.
Sep 23 2014
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 22 September 2014 at 09:39:29 UTC, Don wrote:
 Having said that, though, the success of 'alias this' does 
 raise some interesting questions about how useful the concept 
 of a typedef is. Certainly it's much less useful than when 
 Typedef was created.

 My feeling is that almost every time when you want to create a 
 new type from an existing one, you actually want to restrict 
 the operations which can be performed on it. (Eg if you have  
 typedef money = double; then money*money doesn't make much 
 sense). For most typedefs I think you're better off with 'alias 
 this'.
If you have a look at our transition.d it does exactly that right now - mixes in the struct with the same name as typedef had and does `alias this` for its value field ;)
Sep 23 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 9:05 AM, Dicebot wrote:
 On Monday, 22 September 2014 at 09:39:29 UTC, Don wrote:
 Having said that, though, the success of 'alias this' does raise some
 interesting questions about how useful the concept of a typedef is.
 Certainly it's much less useful than when Typedef was created.

 My feeling is that almost every time when you want to create a new
 type from an existing one, you actually want to restrict the
 operations which can be performed on it. (Eg if you have typedef money
 = double; then money*money doesn't make much sense). For most typedefs
 I think you're better off with 'alias this'.
If you have a look at our transition.d it does exactly that right now - mixes in the struct with the same name as typedef had and does `alias this` for its value field ;)
So why not mix in Typedef? -- Andrei
Sep 23 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 23 September 2014 at 16:19:00 UTC, Andrei 
Alexandrescu wrote:
 So why not mix in Typedef? -- Andrei
Why would I ever want it? Plain struct is absolutely superior to it.
Sep 23 2014
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 9:41 AM, Dicebot wrote:
 On Tuesday, 23 September 2014 at 16:19:00 UTC, Andrei Alexandrescu wrote:
 So why not mix in Typedef? -- Andrei
Why would I ever want it? Plain struct is absolutely superior to it.
worksforme
Sep 23 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, Sep 23, 2014 at 04:41:27PM +0000, Dicebot via Digitalmars-d wrote:
 On Tuesday, 23 September 2014 at 16:19:00 UTC, Andrei Alexandrescu wrote:
So why not mix in Typedef? -- Andrei
Why would I ever want it? Plain struct is absolutely superior to it.
So what are we arguing about here? If struct + alias this trumps Typedef, then we should remove Typedef from Phobos and call it a day. This thread has gone on way too long (and has devolved into thinly-veiled name-calling, sarcasm, and nitpicking on definitions of words -- only inches away from Godwin's Law) without any action. Will anyone object if I submit a PR to get rid of Typedef? :-P T -- Help a man when he is in trouble and he will remember you when he is in trouble again.
Sep 23 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 9:56 AM, H. S. Teoh via Digitalmars-d wrote:
 On Tue, Sep 23, 2014 at 04:41:27PM +0000, Dicebot via Digitalmars-d
 wrote:
 On Tuesday, 23 September 2014 at 16:19:00 UTC, Andrei Alexandrescu
 wrote:
 So why not mix in Typedef? -- Andrei
Why would I ever want it? Plain struct is absolutely superior to it.
So what are we arguing about here? If struct + alias this trumps Typedef, then we should remove Typedef from Phobos and call it a day.
I wouldn't oppose deprecating it. But I think the more fertile direction is improving it.
 This thread has gone on way too long (and has devolved into
 thinly-veiled name-calling, sarcasm, and nitpicking on definitions
 of words -- only inches away from Godwin's Law) without any action.
Agreed.
 Will anyone object if I submit a PR to get rid of Typedef? :-P
I'd say you'd need good justification that (a) current Typedef has no advantage over the struct/alias this idiom; (b) there are no significant ways to improve Typedef in ways that would be difficult to the struct-based approach (e.g. disallow implicit conversion to base type, adding constructors etc). A good start would be to amend the documentation to mention the idiom. Andrei
Sep 23 2014
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 23 September 2014 at 17:36:33 UTC, Andrei 
Alexandrescu wrote:
 (b) there are no significant ways to improve Typedef in ways 
 that would be difficult to the struct-based approach (e.g. 
 disallow implicit conversion to base type, adding constructors 
 etc).
I think disallowing stuff is exactly why typedef (and Typedef) are suboptimal - they are a package approach. And once you start adding configuration options, you get a parameter list so long you might as well just write the struct. I do think there's value in some generic mixins for proxy member forwarding though. Typedef is built on a Proxy mixin but it brings everything. I'd say ideally, we'd break it up into various pieces: mixin Addition; mixin Multiplication; /* these two might come together with mixin Arithmetic; */ mixin Dereferencing; mixin Indexing; you know something like that. So now you can add operations selectively... or add them all with alias this and selectively disable them! mixin template Addition(string proxy = "_") { typeof(this) opBinary(string op : "+")(typeof(this) rhs) { return typeof(this)(mixin(proxy ~ op ~ "rhs." ~ proxy)); } } struct Foo { int _; mixin Addition; /* Foo(10) + Foo(20) now yields Foo(30) */ } struct NoAdd { int _; alias _ this; /* Foo(10) + Foo(20) yields int(30) */ mixin Addition; /* now we have all alias this but addition gives Foo */ disable mixin Multiplication; /* multiply is now statically disallowed */ } These mixins would take a wee bit more care than I showed here and we'd want a battery of building blocks AND common combinations, but I think this would blow even the ideal Typedef utterly out of the water. I think I posted this before, but you don't actually want deferencing of an opaque HANDLE. typedef lets you do that since it thinks it is a void*. alias this lets you do it, since it will implicitly convert. But with the individual feature mixins, alias this, and disable, you can do whatever you want and have pretty short, readable code.
Sep 23 2014
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
Can someone clarify how exactly Typedef should work? I'd love to 
make a pull request to fix up whatever needs fixing, but it seems 
like there are a couple different notions of how it should work, 
and it's quite confusing. This seems very similar to the argument 
over enums (which turned out to not be as implicitly convertible 
to their base types as I thought they were).

double doSomething(double d) { return d + 1.0; }

void main()
{
     typedef double money = 0.0;

     money m = 4.0;
     money n = doSomething(m);
     assert(n == 5.0);

     //Allowed?
     money o = m * n;
     assert(o == 20.0);

     //Allowed?
     money p = m * 2.0;
     assert(p == 8.0);

     //Etc. for the other arithmetic operations

     //Passes or fails?
     assert(!isNaN(p.init));
     //Do typedef'd types inherit the properties
     //of their base classes?
     assert(p.min_normal == double.min_normal);


     typedef float dollars = 0.0f;
     typedef float cents = 0.0f;

     dollars d = 1.0f;
     //Allowed?
     cents c = d;
     cents c = cast(cents)d;
     cents c = cast(float)d;

     //Allowed?
     float f = d
     float f = d - c;
     float f = d - 1.0f;

     //Are these allowed? If so, what
     //are the resultant types?
     auto g = c * d;
     auto h = d * 1.0f;

     //Etc., etc.


     typedef int index;

     int[] arr = [0, 1, 2];
     index a = 1;
     //Allowed?
     assert(arr[a] == 1);
     index b = 4;
     arr ~= b;
}
Sep 23 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tue, 23 Sep 2014 18:02:56 +0000
Meta via Digitalmars-d <digitalmars-d puremagic.com> wrote:

      //Allowed?
      money o =3D m * n;
      assert(o =3D=3D 20.0);
yes.
      //Allowed?
      money p =3D m * 2.0;
      assert(p =3D=3D 8.0);
no.
      //Passes or fails?
      assert(!isNaN(p.init));
passes, as it's 'dobule' descendant.
      //Do typedef'd types inherit the properties
      //of their base classes?
      assert(p.min_normal =3D=3D double.min_normal);
yes.
      typedef float dollars =3D 0.0f;
      typedef float cents =3D 0.0f;
=20
      dollars d =3D 1.0f;
      //Allowed?
      cents c =3D d;
no.
      cents c =3D cast(cents)d;
yes.
      cents c =3D cast(float)d;
no.
      //Allowed?
      float f =3D d
      float f =3D d - c;
      float f =3D d - 1.0f;
no.
      //Are these allowed? If so, what
      //are the resultant types?
      auto g =3D c * d;
      auto h =3D d * 1.0f;
no.
      typedef int index;
=20
      int[] arr =3D [0, 1, 2];
      index a =3D 1;
      //Allowed?
      assert(arr[a] =3D=3D 1);
no.
      index b =3D 4;
      arr ~=3D b;
no. my 0.05 dollars.
Sep 23 2014
prev sibling parent Andrej Mitrovic via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 9/21/14, ketmar via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Sun, 21 Sep 2014 08:15:29 -0700
 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
 wrote:

 alias Int1 = Typedef!(int, "a.Int1");
 alias Int2 = Typedef!(int, "b.Int2");
ah, now that's cool. module system? wut? screw it, we have time-proven manual prefixing!
To be fair we now have __MODULE__. Although it does make the call side a bit ugly. But then again, nothing is stopping anyone from writing a helper template around Typedef that hides all this ugliness, e.g.: ----- // helper alias alias StrongAlias(T, string mod = __MODULE__, size_t line = __LINE__) = Typedef!(T, T.init, format("%s.%s.%s", mod, line, T.stringof)); // usage: alias Int1 = StrongAlias!int; alias Int2 = StrongAlias!int; static assert(!is(Int1 == Int2)); ----- This works for me locally. We could add __COLUMN__ to be extra-safe of course, by then it should be a solved problem.
Sep 21 2014
prev sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 20 Sep 2014 08:25:17 -0700
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 9/19/14, 11:36 PM, Marco Leise wrote:
 Am Fri, 19 Sep 2014 08:02:30 -0700
 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 9/18/14, 11:45 PM, Marco Leise wrote:
 We should probably revert to having real typedefs.
Should not.
Ok, but don't ask me to use alias ALfloat = std.typecons.Typedef!(float, "yummyCookie23"); when it could be typedef ALfloat = float; ! :)
I think this is an entirely palatable idiom: alias ALfloat = std.typecons.Typedef!(float, "ALfloat"); Andrei
Funny that you mention it. I had the exact same thought yesterday and hoped you wouldn't come around with that ... excuse. Actually, that works for me. But it could be DRY and look like typedef ALfloat = float; -- Marco
Sep 21 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 1:52 AM, Marco Leise wrote:
 Am Sat, 20 Sep 2014 08:25:17 -0700
 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 9/19/14, 11:36 PM, Marco Leise wrote:
 Am Fri, 19 Sep 2014 08:02:30 -0700
 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 9/18/14, 11:45 PM, Marco Leise wrote:
 We should probably revert to having real typedefs.
Should not.
Ok, but don't ask me to use alias ALfloat = std.typecons.Typedef!(float, "yummyCookie23"); when it could be typedef ALfloat = float; ! :)
I think this is an entirely palatable idiom: alias ALfloat = std.typecons.Typedef!(float, "ALfloat"); Andrei
Funny that you mention it. I had the exact same thought yesterday and hoped you wouldn't come around with that ... excuse.
Why would anyone hope a valid idiom were not mentioned?
 Actually, that works for me. But it could be DRY and
 look like

    typedef ALfloat = float;
DRY is DRY. Bloating the language is bloating the language. Andrei
Sep 21 2014
next sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Sun, 21 Sep 2014 08:04:39 -0700
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 Why would anyone hope a valid idiom were not mentioned?
It's just what people do when an argument would be detrimental to their own position in an argument. :p Look, I don't feel strongly about it. Just, from an objective point of view, aliases and templates in their current form are no good candidates to implement strongly typed typedefs. The semantics are too different. A proxy struct for example does more cleanly define a new symbol and type with normal lookup rules. But let's not waste our energy on this now. It is after all a convenience feature, not an enabler like shared libraries, ARC or standard logging facilities.
 Actually, that works for me. But it could be DRY and
 look like

    typedef ALfloat = float;  
DRY is DRY. Bloating the language is bloating the language. Andrei
-- Marco
Sep 21 2014
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 10:56 AM, Marco Leise wrote:
 Am Sun, 21 Sep 2014 08:04:39 -0700
 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 Why would anyone hope a valid idiom were not mentioned?
It's just what people do when an argument would be detrimental to their own position in an argument. :p Look, I don't feel strongly about it. Just, from an objective point of view, aliases and templates in their current form are no good candidates to implement strongly typed typedefs. The semantics are too different. A proxy struct for example does more cleanly define a new symbol and type with normal lookup rules. But let's not waste our energy on this now. It is after all a convenience feature, not an enabler like shared libraries, ARC or standard logging facilities.
Wise words, thanks! -- Andrei
Sep 21 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 from an objective
 point of view, aliases and templates in their current form are
 no good candidates to implement strongly typed typedefs. The
 semantics are too different.
Wise words, thanks! -- Andrei
So are you now admitting that Typedef is fundamentally broken? Bye, bearophile
Sep 21 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 11:48 AM, bearophile wrote:
 Andrei Alexandrescu:

 from an objective
 point of view, aliases and templates in their current form are
 no good candidates to implement strongly typed typedefs. The
 semantics are too different.
Wise words, thanks! -- Andrei
So are you now admitting that Typedef is fundamentally broken?
No. -- Andrei
Sep 21 2014
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Sunday, 21 September 2014 at 17:47:57 UTC, Marco Leise wrote:
 Am Sun, 21 Sep 2014 08:04:39 -0700
 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 Why would anyone hope a valid idiom were not mentioned?
It's just what people do when an argument would be detrimental to their own position in an argument. :p Look, I don't feel strongly about it. Just, from an objective point of view, aliases and templates in their current form are no good candidates to implement strongly typed typedefs. The semantics are too different. A proxy struct for example does more cleanly define a new symbol and type with normal lookup rules. But let's not waste our energy on this now. It is after all a convenience feature, not an enabler like shared libraries, ARC or standard logging facilities.
I agree that it is not _that_ important but it feels really bad to have to reimplement parts of standard library to get semantics at least somewhat close to promised/expected. Pretty much only effective difference it makes is that write now I have a custom Typedef wrapper as part of D1->D2 migration helpers and initially hoped for forwarding it to std.typecons.Typedef once migration is over. But considering Andrei strong position on topic it will stay as in-house mixin based solution, not a big deal. I am just surprised Andrei insists so hard on defending solution that is questionable at best.
Sep 21 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 12:11 PM, Dicebot wrote:
 I am just surprised Andrei insists so hard on defending solution
 that is questionable at best.
It's just what the doctor prescribed. A good engineering solution for a minor problem. -- Andrei
Sep 21 2014
prev sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 21 Sep 2014 19:56:48 +0200
Marco Leise via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 It is after all a convenience feature
easy type safety is just "a convient feature"? O_O i'm wordless.
Sep 21 2014
parent reply "Ola Fosheim Grostad" <ola.fosheim.grostad+dlang gmail.com> writes:
On Sunday, 21 September 2014 at 20:49:02 UTC, ketmar via 
Digitalmars-d wrote:
 On Sun, 21 Sep 2014 19:56:48 +0200
 Marco Leise via Digitalmars-d <digitalmars-d puremagic.com> 
 wrote:

 It is after all a convenience feature
easy type safety is just "a convient feature"? O_O i'm wordless.
I am waiting for a patch...
Sep 21 2014
parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sun, 21 Sep 2014 22:07:21 +0000
Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 I am waiting for a patch...
i believe that we should revive 'typedef' keyword, but i'm not fully convinced yet. so i'll wait a little more. but you guessed it right, i'm thinking about another patch. ;-)
Sep 21 2014
next sibling parent "Ola Fosheim Grostad" <ola.fosheim.grostad+dlang gmail.com> writes:
On Sunday, 21 September 2014 at 23:00:09 UTC, ketmar via 
Digitalmars-d wrote:
 i believe that we should revive 'typedef' keyword, but i'm not 
 fully
 convinced yet. so i'll wait a little more. but you guessed it 
 right,
 i'm thinking about another patch. ;-)
It's a nice small project, if I didn't have backlog I'd give it a go. Sounds fun.
Sep 21 2014
prev sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Sunday, 21 September 2014 at 23:00:09 UTC, ketmar via 
Digitalmars-d wrote:
 On Sun, 21 Sep 2014 22:07:21 +0000
 Ola Fosheim Grostad via Digitalmars-d 
 <digitalmars-d puremagic.com>
 wrote:

 I am waiting for a patch...
i believe that we should revive 'typedef' keyword, but i'm not fully convinced yet. so i'll wait a little more. but you guessed it right, i'm thinking about another patch. ;-)
Why not introduce a std.typecons.Newtype(T) with the desired semantics in addition to Typedef(T)? Btw, there is an argument to be made _for_ the current Typedef: If it generates an unpredictable cookie every time it is used (and I would count __LINE__ as one, as it can change easily), it's very hard to keep binary compatibility. Maybe taking only __MODULE__ in consideration would be a good compromise, because it at least avoids accidental cross module hijacking.
Sep 22 2014
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 DRY is DRY. Bloating the language is bloating the language.
To implement a typedef in library code in D perhaps you need a well implemented __gensym__ that works correctly in presence of separate compilation. It can generate a string that contains a progressive number for each D module, plus a digest of the module path and name. Phobos contains hundreds of things, but a large percentage of them doesn't attract the amount of critiques that Typedef has received in many threads. This can suggest you that there is something special in Typedef.
 Sooner or later a dirty semantics will bite your ass.
Mine ain't hurting. -- Andrei
This is not surprising because you say you have not used Typedef much in your code. Bye, bearophile
Sep 21 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/21/14, 12:05 PM, bearophile wrote:
 Andrei Alexandrescu:

 DRY is DRY. Bloating the language is bloating the language.
To implement a typedef in library code in D perhaps you need a well implemented __gensym__ that works correctly in presence of separate compilation.
Nice to have, but not necessary. -- Andrei
Sep 21 2014
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/18/14, 10:53 PM, bearophile wrote:
 Andrei Alexandrescu:

 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I would
 consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart.
No. -- Andrei
Sep 19 2014
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/19/2014 04:59 PM, Andrei Alexandrescu wrote:
 On 9/18/14, 10:53 PM, bearophile wrote:
 Andrei Alexandrescu:

 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I would
 consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart.
No. -- Andrei
Yes.
Sep 19 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/19/14, 5:28 PM, Timon Gehr wrote:
 On 09/19/2014 04:59 PM, Andrei Alexandrescu wrote:
 On 9/18/14, 10:53 PM, bearophile wrote:
 Andrei Alexandrescu:

 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I would
 consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart.
No. -- Andrei
Yes.
No. :o) -- Andrei
Sep 19 2014
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/20/2014 02:29 AM, Andrei Alexandrescu wrote:
 On 9/19/14, 5:28 PM, Timon Gehr wrote:
 On 09/19/2014 04:59 PM, Andrei Alexandrescu wrote:
 On 9/18/14, 10:53 PM, bearophile wrote:
 Andrei Alexandrescu:

 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I would
 consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart.
No. -- Andrei
Yes.
No. :o) -- Andrei
To substantiate: It does the wrong thing (same typedef for same base type) by default and doing the right thing (emulating nominal typing) may require quite some effort in general (e.g. concatenate the mangled names of all enclosing template instantiations) while remaining non-modular (those cookie strings are global identifiers). I.e. Typedef is fail. Won't use. Declaring a new struct and using Proxy, perhaps encapsulated using a mixin template is less trouble (quick hack, results in bad error messages): import std.typecons; mixin template WorkingTypedef(string i,T,T init=T.init)/+if(...)+/{ // workaround for https://issues.dlang.org/show_bug.cgi?id=13500 mixin std.typecons.Typedef!(T,init); mixin(`alias `~i~` =Typedef;`); } mixin WorkingTypedef!("Name1",int); mixin WorkingTypedef!("Name2",int,2); void main(){ Name1 foo; Name2 bar; foo=bar; // error } Feel free to disagree, but I don't see how one can.
Sep 19 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/19/14, 8:14 PM, Timon Gehr wrote:
 On 09/20/2014 02:29 AM, Andrei Alexandrescu wrote:
 On 9/19/14, 5:28 PM, Timon Gehr wrote:
 On 09/19/2014 04:59 PM, Andrei Alexandrescu wrote:
 On 9/18/14, 10:53 PM, bearophile wrote:
 Andrei Alexandrescu:

 Wyatt:
 (I wouldn't consider the cookie parameter a better solution; I would
 consider it a wart.)
That's the right solution.
The cookie parameter is a ugly wart.
No. -- Andrei
Yes.
No. :o) -- Andrei
To substantiate: It does the wrong thing (same typedef for same base type) by default and doing the right thing (emulating nominal typing) may require quite some effort in general (e.g. concatenate the mangled names of all enclosing template instantiations) while remaining non-modular (those cookie strings are global identifiers).
This is wrong but probably not worth fighting. Consider: alias A = Typedef!float; alias B = Typedef!float; By basic language rules, A and B are identical. Making them magically distinct would be surprising and would require explanation. It's as if someone writes: struct Point { int x, y; } alias A = Point; and then later in the same module alias B = Point; and complains that the compiler didn't automagically distinguish between the two. Human-readable cookies are exactly the solution: distinct human-readable moniker that distinguish the types. alias A = Typedef!(float, "dollar"); alias B = Typedef!(float, "euro"); They will be distinct to the human and compiler alone.
 I.e. Typedef is fail. Won't use.
Typedef is win. Feel free to not use.
 Declaring a new struct and using Proxy,
 perhaps encapsulated using a mixin template is less trouble (quick hack,
 results in bad error messages):

 import std.typecons;

 mixin template WorkingTypedef(string i,T,T init=T.init)/+if(...)+/{
      // workaround for https://issues.dlang.org/show_bug.cgi?id=13500
      mixin std.typecons.Typedef!(T,init);
      mixin(`alias `~i~` =Typedef;`);
 }
 mixin WorkingTypedef!("Name1",int);
 mixin WorkingTypedef!("Name2",int,2);

 void main(){
      Name1 foo;
      Name2 bar;
      foo=bar; // error
 }


 Feel free to disagree, but I don't see how one can.
Your argument has been destroyed. Andrei
Sep 19 2014
next sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei 
Alexandrescu wrote:
 [snip]
Um, why not use __FILE__ / __LINE__ (as default values for template parameters) as cookies?
Sep 19 2014
next sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 20 Sep 2014 06:32:38 +0000
schrieb "Vladimir Panteleev" <vladimir thecybershadow.net>:

 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei 
 Alexandrescu wrote:
 [snip]
Um, why not use __FILE__ / __LINE__ (as default values for template parameters) as cookies?
It has this nasty imperfection that it breaks as soon as you define two Typedefs on the same line. Which noone ever does except maybe for an obfuscated coding scenario, but still it raises my OCD level. -- Marco
Sep 20 2014
next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Saturday, 20 September 2014 at 13:49:58 UTC, Marco Leise wrote:
 Am Sat, 20 Sep 2014 06:32:38 +0000
 schrieb "Vladimir Panteleev" <vladimir thecybershadow.net>:

 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei 
 Alexandrescu wrote:
 [snip]
Um, why not use __FILE__ / __LINE__ (as default values for template parameters) as cookies?
It has this nasty imperfection that it breaks as soon as you define two Typedefs on the same line. Which noone ever does except maybe for an obfuscated coding scenario, but still it raises my OCD level.
We could introduce __COLUMN__ trivially now that DMD tracks column numbers :)
Sep 20 2014
prev sibling next sibling parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Marco Leise"  wrote in message 
news:20140920155851.030b1633 marco-leise.homedns.org...

 It has this nasty imperfection that it breaks as soon as you
 define two Typedefs on the same line. Which noone ever does
 except maybe for an obfuscated coding scenario, but still it
 raises my OCD level.
Or inside a template, but that breaks with an explicit cookie as well. template Foo(T) { alias FooIndex = Typedef!(int, "FooIndex"); } static assert(!is(Foo!int == Foo!string));
Sep 20 2014
parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Saturday, 20 September 2014 at 17:05:40 UTC, Daniel Murphy 
wrote:
 "Marco Leise"  wrote in message 
 news:20140920155851.030b1633 marco-leise.homedns.org...

 It has this nasty imperfection that it breaks as soon as you
 define two Typedefs on the same line. Which noone ever does
 except maybe for an obfuscated coding scenario, but still it
 raises my OCD level.
Or inside a template, but that breaks with an explicit cookie as well. template Foo(T) { alias FooIndex = Typedef!(int, "FooIndex"); } static assert(!is(Foo!int == Foo!string));
What if you *want* a Typedef instantiation to be the same for all instantiations of a parent template? I think you can have both if Typedef simply takes an "ARGS...", which defaults to TypeTuple!(__FILE__, __LINE__, __COLUMN__), but in this case can be overridden to TypeTuple!(Foo, T).
Sep 20 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"Vladimir Panteleev"  wrote in message 
news:oadjpzibjneyfutoydct forum.dlang.org...

 What if you *want* a Typedef instantiation to be the same for all 
 instantiations of a parent template?
Declare it outside the template and provide an alias inside. Like you would with any other declaration you wanted common to all instantiations.
 I think you can have both if Typedef simply takes an "ARGS...", which 
 defaults to TypeTuple!(__FILE__, __LINE__, __COLUMN__), but in this case 
 can be overridden to TypeTuple!(Foo, T).
Yeah. If it wasn't for the syntax overhead, the ideal args is something like this: struct MyTypedef_Tag; alias MyTypedef = Typedef!(basetype, init, MyTypedef_Tag);
Sep 22 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/22/14, 11:56 AM, Daniel Murphy wrote:
 "Vladimir Panteleev"  wrote in message
 news:oadjpzibjneyfutoydct forum.dlang.org...

 What if you *want* a Typedef instantiation to be the same for all
 instantiations of a parent template?
Declare it outside the template and provide an alias inside. Like you would with any other declaration you wanted common to all instantiations.
 I think you can have both if Typedef simply takes an "ARGS...", which
 defaults to TypeTuple!(__FILE__, __LINE__, __COLUMN__), but in this
 case can be overridden to TypeTuple!(Foo, T).
Yeah. If it wasn't for the syntax overhead, the ideal args is something like this: struct MyTypedef_Tag; alias MyTypedef = Typedef!(basetype, init, MyTypedef_Tag);
struct MyTypedef_Tag; alias MyTypedef = Typedef!(basetype, init, MyTypedef_Tag.mangleof); should get you off the ground :o). Andrei
Sep 22 2014
prev sibling parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Saturday, 20 September 2014 at 13:49:58 UTC, Marco Leise wrote:
 Am Sat, 20 Sep 2014 06:32:38 +0000
 schrieb "Vladimir Panteleev" <vladimir thecybershadow.net>:

 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei 
 Alexandrescu wrote:
 [snip]
Um, why not use __FILE__ / __LINE__ (as default values for template parameters) as cookies?
It has this nasty imperfection that it breaks as soon as you define two Typedefs on the same line. Which noone ever does except maybe for an obfuscated coding scenario, but still it raises my OCD level.
https://github.com/D-Programming-Language/phobos/pull/300#issuecomment-3329507
Sep 20 2014
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/19/14, 11:32 PM, Vladimir Panteleev wrote:
 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei Alexandrescu wrote:
 [snip]
Um, why not use __FILE__ / __LINE__ (as default values for template parameters) as cookies?
We could, but that would be surprising. I'd say things are good as they are. -- Andrei
Sep 20 2014
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei 
Alexandrescu wrote:
 This is wrong but probably not worth fighting. Consider:

 alias A = Typedef!float;
 alias B = Typedef!float;

 By basic language rules, A and B are identical. Making them 
 magically distinct would be surprising and would require 
 explanation. It's as if someone writes:

 struct Point { int x, y; }
 alias A = Point;

 and then later in the same module

 alias B = Point;
But Typedef is not some generic symbol. It is library type specifically introduced as `typedef` keyword replacement and advertised as such. I expect it to work as close to `typedef` as possible being the most priority. Otherwise it is simply useless.
 I.e. Typedef is fail. Won't use.
Typedef is win. Feel free to not use.
Thanks for permitting, this is exactly what I will do.
Sep 19 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/19/14, 11:50 PM, Dicebot wrote:
 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei Alexandrescu wrote:
 This is wrong but probably not worth fighting. Consider:

 alias A = Typedef!float;
 alias B = Typedef!float;

 By basic language rules, A and B are identical. Making them magically
 distinct would be surprising and would require explanation. It's as if
 someone writes:

 struct Point { int x, y; }
 alias A = Point;

 and then later in the same module

 alias B = Point;
But Typedef is not some generic symbol. It is library type specifically introduced as `typedef` keyword replacement and advertised as such. I expect it to work as close to `typedef` as possible being the most priority. Otherwise it is simply useless.
No. -- Andrei
Sep 20 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Saturday, 20 September 2014 at 15:26:37 UTC, Andrei 
Alexandrescu wrote:
 But Typedef is not some generic symbol. It is library type 
 specifically
 introduced as `typedef` keyword replacement and advertised as 
 such. I
 expect it to work as close to `typedef` as possible being the 
 most
 priority. Otherwise it is simply useless.
No. -- Andrei
I don't really care what you think. There is a simple fact - there is not a single use case I am going to use existing implementation instead of rolling one of my own. Call me a pervert but when standard library type can't be used for something it was initially proposed for it does smell like a failure.
Sep 20 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/20/14, 8:51 AM, Dicebot wrote:
 On Saturday, 20 September 2014 at 15:26:37 UTC, Andrei Alexandrescu wrote:
 But Typedef is not some generic symbol. It is library type specifically
 introduced as `typedef` keyword replacement and advertised as such. I
 expect it to work as close to `typedef` as possible being the most
 priority. Otherwise it is simply useless.
No. -- Andrei
I don't really care what you think.
You should if I'm right :o).
 There is a simple fact - there is
 not a single use case I am going to use existing implementation instead
 of rolling one of my own. Call me a pervert but when standard library
 type can't be used for something it was initially proposed for it does
 smell like a failure.
But it can be used. You are quick to claim "failure" just because you can't bring yourself to use a simple idiom. Type the blessed string and you're done. So my understanding is your reasoning goes like this: alias Dollar = Typedef!double; // fantastic alias Dollar = Typedef!(double, "Dollar"); // failure I would agree it's not as convenient as a built-in language feature, but it's eminently usable and in fact quite nice because it gives you access to a nice moniker that can be used, e.g. alias Dollar = Typedef!(double, "$"); // yum In the latter case you go on your own and write a bunch of code because you refuse to... type a few characters. I hope you understand why it's difficult to carry any compelling point with such arguments. Andrei
Sep 20 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 But it can be used.
Have you used it in your real D code three or more times? I have tried and I have found many problems. Bye, bearophile
Sep 20 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/20/14, 10:13 AM, bearophile wrote:
 Andrei Alexandrescu:

 But it can be used.
Have you used it in your real D code three or more times?
No, but that doesn't mean much.
 I have tried
 and I have found many problems.
Then fix them. Most of the stuff at https://issues.dlang.org/buglist.cgi?f1=short_desc&list_id=106755&o1=casesubstring&query_format=advanced&resol tion=---&v1=Typedef is trivially fixable. Should take you all of a morning to fix most or all of those. Just do it! Andrei
Sep 20 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 Have you used it in your real D code three or more times?
No, but that doesn't mean much.
It means that I have more experience than you in using Typedef, and in my experience their usage is not so good. Bye, bearophile
Sep 20 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/20/14, 1:52 PM, bearophile wrote:
 Andrei Alexandrescu:

 Have you used it in your real D code three or more times?
No, but that doesn't mean much.
It means that I have more experience than you in using Typedef, and in my experience their usage is not so good.
Aye. What I meant was "it doesn't mean Typedef is unusable; I just didn't need for that particular facility". What I'm saying after skimming https://issues.dlang.org/buglist.cgi?f1=short_desc&list_id=106755&o1=casesubstring&query_format=advanced&resol tion=---&v1=Typedef is that all or at least most issues are trivial to fix. My perception of this thread is that there's an abundance of that misleading vividness fallacy (http://en.wikipedia.org/wiki/Misleading_vividness). Rhetoric techniques blow the most trivial matters out of proportion and build to the foaming co(ncl|f)usion that "less convenient than a baked-in facility" really means "unusable". I don't care for that kind of argument. Fix that stuff, go your merry way and use Typedef. Andrei
Sep 20 2014
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/21/2014 12:08 AM, Andrei Alexandrescu wrote:
 My perception of this thread is that there's an abundance of that misleading
vividness
 fallacy (http://en.wikipedia.org/wiki/Misleading_vividness). Rhetoric
techniques blow
 the most trivial matters out of proportion and build to the foaming
co(ncl|f)usion
 that "less convenient than a baked-in facility" really means "unusable".
 I don't care for that kind of argument.
Make sure to not fall prey to http://en.wikipedia.org/wiki/Argument_from_fallacy though. On 09/22/2014 12:22 AM, Andrei Alexandrescu wrote:
 I don't mind the capitalization, ad hominem, etc. The arguments against
 Typedef are honestly terrible (by all participants), ...
Some participants have pointed out (some more vivdly than others) that it is less convenient and less sane than a trivial library alternative using e.g. template mixins. There's currently simply too much incentive to roll one's own that does the job better if the functionality is at all required. That's not a "terrible" argument.
Sep 21 2014
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/20/2014 06:52 AM, Andrei Alexandrescu wrote:
 On 9/19/14, 8:14 PM, Timon Gehr wrote:
 ....
 To substantiate: It does the wrong thing (same typedef for same base
 type) by default and doing the right thing (emulating nominal typing)
 may require quite some effort in general (e.g. concatenate the mangled
 names of all enclosing template instantiations) while remaining
 non-modular (those cookie strings are global identifiers).
This is wrong
Well, how?
 but probably not worth fighting.
"Then don't bring it up." :o)
 Consider:

 alias A = Typedef!float;
 alias B = Typedef!float;

 By basic language rules, A and B are identical.
I don't see the relevance, but the definition of Typedef is also important to decide whether they are identical, not just language rules.
 Making them magically distinct ...
(Straw man.)
 Human-readable cookies are exactly the solution: distinct human-readable
 moniker that distinguish the types.

 alias A = Typedef!(float, "dollar");
 alias B = Typedef!(float, "euro");
 ...
This doesn't compile. This, IMHO more _ugly_, code compiles: import std.typecons; alias A = Typedef!(float, float.init, "dollar"); alias B = Typedef!(float, float.init, "euro"); // (different issue: void main(){ A dollars=2; B euros=2*dollars; }//)
 They will be distinct to the human and compiler alone.
 ...
Library A: alias A = Typedef!(int, -1, "handle"); Library B: alias B = Typedef!(int, -1, "handle"); // --- template Fun(S,T)/+if(...)+/{ alias Hun=Typedef!(S,S.init,"hun"); // (BTW: what do I do if S or T has no default initializer?) alias Gun=Typedef!(T,T.init,"gun"); // ... } Now e.g. Fun!(int,double).Hun is compatible with Fun!(int,string).Hun. This was my argument. IMO this state of affairs is ugly. Disagree that this makes the cookie parameter an 'ugly wart', but don't call the argument factually wrong without substantiation, please.
 ...

 Your argument has been destroyed.
...
My argument hasn't been considered. To destroy its relevance without consideration would need a very compelling case for the beauty of the cookie parameter, which I haven't seen yet, and it is hard for me to imagine it being made without addressing the above issues. And besides, it is probably highly subjective. Apparently you find the cookie parameter to be pretty because it seems to work for the dollar/euro example (after fixing), while I have a different set of expectations. (BTW: Note that I am not arguing for bringing back built-in typedef.)
Sep 20 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Timon Gehr:

 alias A = Typedef!(float, "dollar");
 alias B = Typedef!(float, "euro");
 ...
This doesn't compile. This, IMHO more _ugly_, code compiles: import std.typecons; alias A = Typedef!(float, float.init, "dollar"); alias B = Typedef!(float, float.init, "euro");
See: https://d.puremagic.com/issues/show_bug.cgi?id=11828 Some other open issues/ERs: https://issues.dlang.org/buglist.cgi?f1=short_desc&o1=casesubstring&query_format=advanced&resolution=---&v1=Typedef Bye, bearophile
Sep 20 2014
parent "Meta" <jared771 gmail.com> writes:
On Saturday, 20 September 2014 at 16:34:17 UTC, bearophile wrote:
 See:
 https://d.puremagic.com/issues/show_bug.cgi?id=11828

 Some other open issues/ERs:
 https://issues.dlang.org/buglist.cgi?f1=short_desc&o1=casesubstring&query_format=advanced&resolution=---&v1=Typedef

 Bye,
 bearophile
This issue https://issues.dlang.org/show_bug.cgi?id=12031 looks like it has been fixed. Can you take a look and close it if that is the case?
Sep 23 2014
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/20/14, 9:07 AM, Timon Gehr wrote:
 On 09/20/2014 06:52 AM, Andrei Alexandrescu wrote:
 On 9/19/14, 8:14 PM, Timon Gehr wrote:
 ....
 To substantiate: It does the wrong thing (same typedef for same base
 type) by default and doing the right thing (emulating nominal typing)
 may require quite some effort in general (e.g. concatenate the mangled
 names of all enclosing template instantiations) while remaining
 non-modular (those cookie strings are global identifiers).
This is wrong
Well, how?
 but probably not worth fighting.
"Then don't bring it up." :o)
Fair enough. It's just that... the tanks are coming and I'm to worry about the bayonet needing some grease instead of setting up the shaped charges. It's misplaced focus.
 Human-readable cookies are exactly the solution: distinct human-readable
 moniker that distinguish the types.

 alias A = Typedef!(float, "dollar");
 alias B = Typedef!(float, "euro");
 ...
This doesn't compile. This, IMHO more _ugly_, code compiles: import std.typecons; alias A = Typedef!(float, float.init, "dollar"); alias B = Typedef!(float, float.init, "euro");
Uhm, apparently I haven't tried the code :o). (Well prolly I'd want to use 0.0 as initializer there, too.)
 // (different issue:
 void main(){
      A dollars=2;
      B euros=2*dollars;
 }//)
Ew, that looks like a bug. How does that conversion go through? Could you please file an issue?
 They will be distinct to the human and compiler alone.
 ...
Library A: alias A = Typedef!(int, -1, "handle"); Library B: alias B = Typedef!(int, -1, "handle"); // ---
Yup, yup, say no more. I get your point. Clearly there's some due diligence necessary here, i.e. prefix the name with the module name etc.
 This was my argument. IMO this state of affairs is ugly. Disagree that
 this makes the cookie parameter an 'ugly wart', but don't call the
 argument factually wrong without substantiation, please.
OK, fair enough. Thanks. Andrei
Sep 20 2014
prev sibling parent reply "Wyatt" <wyatt.epp gmail.com> writes:
On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei 
Alexandrescu wrote:
 alias A = Typedef!float;
 alias B = Typedef!float;

 By basic language rules, A and B are identical. Making them 
 magically distinct would be surprising...
Hold up. See, "Making them magically distinct would be surprising" is really the sticking point for me because in my experience it rings false. When I reach for a typedef, I expect these things to NOT be identical. More to the point, I'm explicitly stating: "This thing is not like any other thing." That's the fundamental reason any sort of typedef exists in my world. That the idiomatic library Typedef doesn't actually give these semantics unless I do extra stuff? _That_ is surprising and inconvenient. I'm personally having difficulty coming up with a situation where the current default behaviour is even useful. You can make the argument that it's not that much of a burden. And on a cursory read, sure, that makes enough sense. But it's still there and still acts as positive punishment. We tend to tout type safety as a major feature, which builds the expectation that getting it for the common case is _completely trivial_ and in-line with the pragmatic approach taken by the rest of the language. Adding a gotcha like this makes it less likely to be used correctly. And I think it needs to be stressed: No one is arguing that the current behaviour shouldn't be possible at all; just that it's an unusual special case that makes for a warty default. If you want two distinctly-named types to hash the same, give them a common cookie and be on your merry way. Meanwhile, the issues with e.g. Typedef in templates disappear because it makes introducing a unique type the trivial default. Anecdotally, I was explaining how neat it is that D has library Typedef to an engineer on my team and he commented that he'd never expect a word like "alias" to be associated with defining a distinct type, suggesting its use here is a misfeature. He also called the cookie parameter a wart (unprompted). -Wyatt
Sep 22 2014
next sibling parent "eles" <eles215 gzk.dot> writes:
On Monday, 22 September 2014 at 16:21:43 UTC, Wyatt wrote:
 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei 
 Alexandrescu wrote:
 alias A = Typedef!float;
 alias B = Typedef!float;

 By basic language rules, A and B are identical. Making them 
 magically distinct would be surprising...
Hold up. See, "Making them magically distinct would be surprising" is really the sticking point for me because in my experience it rings false. When I reach for a typedef, I expect these things to NOT be identical. More to the point, I'm explicitly stating: "This thing is not like any other thing." That's the fundamental reason any sort of typedef exists in my world.
IIRC, in the beginning, typedef was (assumed to be) just that. The problem was that the conversion rules lacked and, finally, nobody wrote them. Typedef itself became deprecated and merely a synonim for "alias". Too bad, since the "strong typedef" was one of the things that dragged me into D from the C world...
Sep 22 2014
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/22/14, 9:21 AM, Wyatt wrote:
 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei Alexandrescu wrote:
 alias A = Typedef!float;
 alias B = Typedef!float;

 By basic language rules, A and B are identical. Making them magically
 distinct would be surprising...
Hold up. See, "Making them magically distinct would be surprising" is really the sticking point for me because in my experience it rings false. When I reach for a typedef, I expect these things to NOT be identical. More to the point, I'm explicitly stating: "This thing is not like any other thing." That's the fundamental reason any sort of typedef exists in my world. That the idiomatic library Typedef doesn't actually give these semantics unless I do extra stuff? _That_ is surprising and inconvenient. I'm personally having difficulty coming up with a situation where the current default behaviour is even useful.
I would agree with that. If I'd do it over again I'd probably make the string the second argument with no default.
 You can make the argument that it's not that much of a burden. And on a
 cursory read, sure, that makes enough sense.
It's a good argument. At some point some RTFM is necessary; I think it's reasonable to assume that whoever is in the market for using Typedef would spend a minute with the documentation.
 But it's still there and
 still acts as positive punishment.  We tend to tout type safety as a
 major feature, which builds the expectation that getting it for the
 common case is _completely trivial_ and in-line with the pragmatic
 approach taken by the rest of the language.  Adding a gotcha like this
 makes it less likely to be used correctly.
Type safety is not the problem here. I do agree that surprising behavior for those who don't RTFM is possible.
 And I think it needs to be stressed: No one is arguing that the current
 behaviour shouldn't be possible at all; just that it's an unusual
 special case that makes for a warty default.
I'd agree with that. (Again if I could do things over again there'd be no default for the cookie.) But my understanding is that there's quite a bit of blowing this out of proportion.
 If you want two
 distinctly-named types to hash the same, give them a common cookie and
 be on your merry way.  Meanwhile, the issues with e.g. Typedef in
 templates disappear because it makes introducing a unique type the
 trivial default.

 Anecdotally, I was explaining how neat it is that D has library Typedef
 to an engineer on my team and he commented that he'd never expect a word
 like "alias" to be associated with defining a distinct type, suggesting
 its use here is a misfeature.  He also called the cookie parameter a
 wart (unprompted).
It's an anecdote. How you explained matters matters a lot :o). I find the requirement for the cookie perfect. Andrei
Sep 22 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 I find the requirement for the cookie perfect.
So far you're the only one, it seems. And you have admitted you have not tried to use them significantly in your code. Bye, bearophile
Sep 22 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/22/14, 11:35 AM, bearophile wrote:
 Andrei Alexandrescu:

 I find the requirement for the cookie perfect.
So far you're the only one, it seems. And you have admitted you have not tried to use them significantly in your code.
Well there seem to be a sore need of arguments to convince me otherwise. Best one was a triple "u" in "ugly". -- Andrei
Sep 22 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Mon, 22 Sep 2014 16:05:38 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 Best one was a triple "u" in "ugly".
there were four "u"s, but my mail program makes uuugly like breaks with four "u"s.
Sep 22 2014
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 22 September 2014 at 17:21:50 UTC, Andrei Alexandrescu 
wrote:
 I find the requirement for the cookie perfect.
There is one thing I like about it and wish was available elsewhere: two modules can define the same type for interoperability without needing to import each other. My simpledisplay.d and image.d modules both used to be standalone. Both defined struct Color {}. Identical layout. When I added optional integration, these two structs clashed. The solution was to introduce module color, which held that struct. But now both modules require that import. Works fine but I think it would have been great if I could have kept the two separate definitions and just told the compiler it's ok, these two types are indeed identically compatible despite coming from independent modules. kinda like pragma(mangle) but for types and preferably less hacky. Another potential use of this concept would be separate interface and implementation files. But that's all pretty different than the Typedef cookie. I'm just saying it because the concept of matching types in different modules IS something that I've wanted in the past.
Sep 22 2014
prev sibling parent reply "Wyatt" <wyatt.epp gmail.com> writes:
On Monday, 22 September 2014 at 17:21:50 UTC, Andrei Alexandrescu 
wrote:
 I would agree with that. If I'd do it over again I'd probably 
 make the string the second argument with no default.
That's not the problem though.
 You can make the argument that it's not that much of a burden. 
 And on a cursory read, sure, that makes enough sense.
It's a good argument. At some point some RTFM is necessary; I think it's reasonable to assume that whoever is in the market for using Typedef would spend a minute with the documentation.
Even just reading this thread, I can see that the people in the market for using Typedef also want to use it _often_ (a sentiment I echo) because trivial type safety is such a compelling feature. The fact that it's documented is beside the point. (I thought you or Walter talked before about how "RTFM" isn't a shining endorsement of your API?) The fact that its primary use isn't the default presents a usability problem. For one thing, no one likes writing boilerplate. It's annoying. When things are annoying, people find some other way. But there's another aspect that makes this even worse (below).
 Type safety is not the problem here. I do agree that surprising 
 behavior for those who don't RTFM is possible.
I beg to differ. Type safety is the entire goal. Surprising behaviour shouldn't be the default when the "Surprise!" part is that it doesn't break until later. That surprises should explode spectacularly at their earliest convenience is a lesson you taught me with e.g. the rationale behind using NaN as the floating point init value. By failing to detonate, errors can manifest in the implementation subtly after appearing to work for an extended period. This is bad. You said earlier it's reasonable to assume people would read the docs, and I agree to an extent. But I think it's reasonable to want APIs in the standard library that are resistant to misreading, skimming, and misunderstanding. That very sort of confusion is why this thread even started, after all! And the solution in this case is conceptually simple.
 I'd agree with that. (Again if I could do things over again 
 there'd be no default for the cookie.) But my understanding is
Generating a unique cookie if one isn't given is the correct behaviour from the _user's_ perspective. I believe it also addresses the concerns Timon raised regarding Typedef in templates.
 that there's quite a bit of blowing this out of proportion.
I agree some of the discussion has been hyperbolic, but I also agree there's a real problem with the current situation that goes beyond simply "this is moderately annoying".
 It's an anecdote. How you explained matters matters a lot :o). 
 I find the requirement for the cookie perfect.
Something like, "Look how cool it is that we can do typedefs as a template!" and a link to the docs. Just an anecdote from a non-D user that ended up being relevant. (I'm trying to score converts! ;) -Wyatt
Sep 23 2014
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/23/14, 8:10 AM, Wyatt wrote:
 On Monday, 22 September 2014 at 17:21:50 UTC, Andrei Alexandrescu wrote:
 I would agree with that. If I'd do it over again I'd probably make the
 string the second argument with no default.
That's not the problem though.
 You can make the argument that it's not that much of a burden. And on
 a cursory read, sure, that makes enough sense.
It's a good argument. At some point some RTFM is necessary; I think it's reasonable to assume that whoever is in the market for using Typedef would spend a minute with the documentation.
Even just reading this thread, I can see that the people in the market for using Typedef also want to use it _often_ (a sentiment I echo) because trivial type safety is such a compelling feature.
I'm not buying this. Yah, there's batteries of types a la Windows' definitions, but it's not like casual use everywhere.
 The fact that
 it's documented is beside the point. (I thought you or Walter talked
 before about how "RTFM" isn't a shining endorsement of your API?)
Sure, the lesser the better. But it's a continuum, not beside the point.
 The
 fact that its primary use isn't the default presents a usability
 problem.  For one thing, no one likes writing boilerplate.  It's
 annoying.  When things are annoying, people find some other way.  But
 there's another aspect that makes this even worse (below).
Then define and use defineTypedef. Clearly there's an imbalance between the desire of getting work done with Typedef and that of ildly arguing that Typedef is useless. People who need to get work done won't be stopped by Typedef. They'll type it twice and if they need it a third time then they'll figure how to simplify its usage. Or they use Adam's idiom (Adam makes this point in his epic slideless talk: just get into it and make it work! I've never seem Adam working himself to a foam over minutia.)
 Type safety is not the problem here. I do agree that surprising
 behavior for those who don't RTFM is possible.
I beg to differ. Type safety is the entire goal.
That's a loose use of the term.
 Surprising behaviour
 shouldn't be the default when the "Surprise!" part is that it doesn't
 break until later.  That surprises should explode spectacularly at their
 earliest convenience is a lesson you taught me with e.g. the rationale
 behind using NaN as the floating point init value.  By failing to
 detonate, errors can manifest in the implementation subtly after
 appearing to work for an extended period.  This is bad.
Not buying all this, sorry.
 You said earlier it's reasonable to assume people would read the docs,
 and I agree to an extent.  But I think it's reasonable to want APIs in
 the standard library that are resistant to misreading, skimming, and
 misunderstanding.  That very sort of confusion is why this thread even
 started, after all!
The guy who started this thread was explained what to do, replied with "Sorry, my mistake" and went on his way getting stuff done.
 And the solution in this case is conceptually simple.
What would that be?
 I'd agree with that. (Again if I could do things over again there'd be
 no default for the cookie.) But my understanding is
Generating a unique cookie if one isn't given is the correct behaviour from the _user's_ perspective. I believe it also addresses the concerns Timon raised regarding Typedef in templates.
I'd be fine with improving Typedef. In fact part of the rationale for replacing the built-in with a library type is that we have more flexibility in library space.
 that there's quite a bit of blowing this out of proportion.
I agree some of the discussion has been hyperbolic, but I also agree there's a real problem with the current situation that goes beyond simply "this is moderately annoying".
 It's an anecdote. How you explained matters matters a lot :o). I find
 the requirement for the cookie perfect.
Something like, "Look how cool it is that we can do typedefs as a template!" and a link to the docs. Just an anecdote from a non-D user that ended up being relevant. (I'm trying to score converts! ;)
That's great. Andrei
Sep 23 2014
prev sibling parent reply ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Mon, 22 Sep 2014 16:21:42 +0000
Wyatt via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 On Saturday, 20 September 2014 at 04:52:58 UTC, Andrei=20
 Alexandrescu wrote:
 alias A =3D Typedef!float;
 alias B =3D Typedef!float;

 By basic language rules, A and B are identical. Making them=20
 magically distinct would be surprising...
Hold up. See, "Making them magically distinct would be=20 surprising" is really the sticking point for me because in my=20 experience it rings false.
it's abusing 'alias' which makes it all a mess. if we look at the code above as 'idiomatic D code', then A and B should be similar. but if we looking at the code as 'hacky replacement for real typedef', A and B should not be similar. seems that Andrei talking about 'idiomatic D' and we are talking about 'hacky typedef replacement'. that's why we can't settle the issue: we are both right! ;-) and that's why we need 'typedef' revived, methinks.
Sep 22 2014
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/22/14, 11:52 AM, ketmar via Digitalmars-d wrote:
 seems that Andrei talking about 'idiomatic D' and we are talking about
 'hacky typedef replacement'. that's why we can't settle the issue: we
 are both right! ;-)
That I'd agree with.
 and that's why we need 'typedef' revived, methinks.
Sorry, no. Andrei
Sep 22 2014
parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Mon, 22 Sep 2014 16:06:42 -0700
Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com>
wrote:

 On 9/22/14, 11:52 AM, ketmar via Digitalmars-d wrote:
 seems that Andrei talking about 'idiomatic D' and we are talking
 about 'hacky typedef replacement'. that's why we can't settle the
 issue: we are both right! ;-)
That I'd agree with.
yeah, and then your resistance to turn 'idiomatic D' to 'hacky typedef' is completely understandable. it took me a while to realise that we are talking about different things here.
 and that's why we need 'typedef' revived, methinks.
Sorry, no.
"Typedef" is elegant and "typedef" is handy. why can't we have both? at least until AST macros arrives (and then we'll make "typedef", "deftype" and "gimmeacheese" ;-). let's limit "typedef" to simple numeric types and pointers to simple numeric types to ease implementation. sure, we'll be able to multiple money by money but not money by float then, but i found this acceptable, we always can write a free function which multiples our money. ;-)
Sep 22 2014
prev sibling next sibling parent reply "Freddy" <Hexagonalstar64 gmail.com> writes:
Is this supposed to happen?
---
import std.typecons;

alias feet=Typedef!(float,0.0,"feet");
alias meter=Typedef!(float,0.0,"meter");

void main(){
	feet a=4.0;
	meter b=5.0;
	meter c=a*b;//opps
	pragma(msg,typeof(c));
}
---
$dmd -o- typetest.d
Typedef!(float, 0.00000F, "meter")
Sep 21 2014
parent "Freddy" <Hexagonalstar64 gmail.com> writes:
On Sunday, 21 September 2014 at 18:24:53 UTC, Freddy wrote:
 Is this supposed to happen?
 ---
 import std.typecons;

 alias feet=Typedef!(float,0.0,"feet");
 alias meter=Typedef!(float,0.0,"meter");

 void main(){
 	feet a=4.0;
 	meter b=5.0;
 	meter c=a*b;//opps
 	pragma(msg,typeof(c));
 }
 ---
 $dmd -o- typetest.d
 Typedef!(float, 0.00000F, "meter")
nevermind the build-in typedef is worse --- typedef float feet; typedef float meter; void main(){ feet a=cast(feet)4.0;//these are required meter b=cast(meter)5.0; auto c=a*b;//opps pragma(msg,typeof(c)); } --- $dmd type.d -o- type.d(1): Deprecation: use of typedef is deprecated; use alias instead type.d(2): Deprecation: use of typedef is deprecated; use alias instead meter
Sep 21 2014
prev sibling parent reply Shammah Chancellor <email domain.com> writes:
What exactly was wrong with the original typedef statement that was deprecated?
Sep 22 2014
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 23 September 2014 at 00:01:51 UTC, Shammah Chancellor 
wrote:
 What exactly was wrong with the original typedef statement that 
 was deprecated?
I personally find it too inflexible; it virtually never does exactly what I need. BTW I've never used std.typecons.Typedef for the same reason. But what are some examples of typedef? HANDLE and HMENU are close to useful indeed, I've used typedef for that kind of thing before. But it isn't perfect: do you ever want do do *handle? That's allowed with typedef. Do you want it to explicitly cast to void*? That's allowed with typedef. People couldn't agree on if typedef should be a subtype or a separate type either, which fed the deprecation. Personally though I think that's silly, if what it does is well defined, we can keep it and do other things for the other cases. But it does need to be compelling over another feature to be kept and I'm not sure it is. So I tend to prefer struct and a little alias this and disabled overloads to a typedef. A wee bit more verbose, but more flexible and correct too.
Sep 22 2014
parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Tue, Sep 23, 2014 at 12:13:19AM +0000, Adam D. Ruppe via Digitalmars-d wrote:
 On Tuesday, 23 September 2014 at 00:01:51 UTC, Shammah Chancellor wrote:
What exactly was wrong with the original typedef statement that was
deprecated?
I personally find it too inflexible; it virtually never does exactly what I need. BTW I've never used std.typecons.Typedef for the same reason. But what are some examples of typedef? HANDLE and HMENU are close to useful indeed, I've used typedef for that kind of thing before. But it isn't perfect: do you ever want do do *handle? That's allowed with typedef. Do you want it to explicitly cast to void*? That's allowed with typedef. People couldn't agree on if typedef should be a subtype or a separate type either, which fed the deprecation. Personally though I think that's silly, if what it does is well defined, we can keep it and do other things for the other cases. But it does need to be compelling over another feature to be kept and I'm not sure it is. So I tend to prefer struct and a little alias this and disabled overloads to a typedef. A wee bit more verbose, but more flexible and correct too.
Yeah, I think struct + alias this + function/operator overloading pretty much does whatever typedef may have done, except better. So I personally don't miss typedef at all (not Typedef, for that matter). T -- Freedom: (n.) Man's self-given right to be enslaved by his own depravity.
Sep 22 2014