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

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