September 23, 2014
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
September 23, 2014
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
September 23, 2014
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


September 23, 2014
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.
September 23, 2014
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

September 23, 2014
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.
September 23, 2014
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;
}

September 23, 2014
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.


September 23, 2014
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 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.


September 23, 2014
On Tue, 23 Sep 2014 18:02:56 +0000
Meta via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

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

>      //Allowed?
>      money p = m * 2.0;
>      assert(p == 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 == double.min_normal);
yes.

>      typedef float dollars = 0.0f;
>      typedef float cents = 0.0f;
> 
>      dollars d = 1.0f;
>      //Allowed?
>      cents c = d;
no.

>      cents c = cast(cents)d;
yes.

>      cents c = cast(float)d;
no.

>      //Allowed?
>      float f = d
>      float f = d - c;
>      float f = d - 1.0f;
no.

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

>      typedef int index;
> 
>      int[] arr = [0, 1, 2];
>      index a = 1;
>      //Allowed?
>      assert(arr[a] == 1);
no.

>      index b = 4;
>      arr ~= b;
no.

my 0.05 dollars.