www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - typedef, Typedef

reply "bearophile" <bearophileHUGS lycos.com> writes:
This works if you compile with the -d switch:


void main() {
     typedef int T;
     T[10] a1;
     a1[] = 10;
     T[] a2 = [1, 2, 3];
     T[T] aa = [1:2, 3:4];
}



std.typecons.Typedef should replace the built-in typedef, but 
currently you can't use it in those cases:


void main() {
     import std.typecons: Typedef;
     alias T = Typedef!int;
     T[10] a1;
     a1[] = T(10); // OK
     a1[] = 10; // Error
     T[] a2 = [1, 2, 3]; // Error
     T[T] aa = [1:2, 3:4]; // Error
}


The problem with "a1[] = 10;":
http://d.puremagic.com/issues/show_bug.cgi?id=6523


But this use case is more important:
T[] a2 = [1, 2, 3];

Workarounds:
T[] a2 = [T(1), T(2), T(3)];
T[T] aa = [T(1):T(2), T(3):T(4)];
T[] a2 = [1, 2, 3].map!T.array;
T[T] aa = zip([1,3].map!T, [2,4].map!T).assocArray;


But both workarounds are bad when you have many items, a long 
name for the typedef, or your T is the type of the keys or values 
of an associative array.

Can this situation be fixed/improved?

Bye,
bearophile
Nov 23 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 23 November 2013 at 20:55:45 UTC, bearophile wrote:
 Can this situation be fixed/improved?

 Bye,
 bearophile
By returning typedef back.
Nov 23 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Maxim Fomin:

 By returning typedef back.
I think Andrei wants to answer you: 'E's passed on! typedef is no more! He has ceased to be! 'E's expired and gone to meet 'is maker! 'E's a stiff! Bereft of life, 'e rests in peace! 'E's off the twig! 'E's kicked the bucket, 'e's shuffled off 'is mortal coil, run down the curtain and joined the bleedin' choir invisible! Now, back to making Typedef awesome. Bye, bearophile
Nov 23 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
The problem with "T[] a2 = [1, 2, 3];" was reported here:
http://d.puremagic.com/issues/show_bug.cgi?id=8864

And it was discussed a bit here:
http://forum.dlang.org/thread/tyrleoromnxjhvfodmbe forum.dlang.org

-----------------------

Other problems with Typedef:

http://d.puremagic.com/issues/show_bug.cgi?id=7777


import std.typecons: Typedef;
alias V3 = Typedef!(double[3]);
V3 v1 = [30, 30, -50]; // error
V3 v2 = V3([30, 30, -50]); // OK
void main() {
     V3 v3 = [30, 30, -50]; // OK
     V3 v4 = V3([30, 30, -50]); // OK
}

-----------------------

http://d.puremagic.com/issues/show_bug.cgi?id=9363

import std.typecons: Typedef;
alias Typedef!(ubyte[]) MyArray;
void main() {
     MyArray arr;
     arr.length = 10;
     arr[] = 0; // error
}

-----------------------

http://d.puremagic.com/issues/show_bug.cgi?id=10778

This works:

alias Matrix = double[260][260];
typedef Matrix Foo;
void main() {
     Foo m;
}


This fails:

import std.typecons: Typedef;
alias Matrix = double[260][260];
alias Foo = Typedef!Matrix; // template recursive expansion error
void main() {}

-----------------------

Plus a const-related issue that seems simpler to fix:
http://d.puremagic.com/issues/show_bug.cgi?id=7737
http://d.puremagic.com/issues/show_bug.cgi?id=11584

Bye,
bearophile
Nov 23 2013
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/23/13 12:55 PM, bearophile wrote:
 But both workarounds are bad when you have many items, a long name for
 the typedef, or your T is the type of the keys or values of an
 associative array.

 Can this situation be fixed/improved?
Typedef!T is meant as a type with the same behavior as T, but otherwise unrelated to it. The code above suggests it behaves as advertised. Allowing uncontrolled conversions to and fro is only making typedef weaker. Asking for features just because "they worked with typedef" is unlikely to fare well because typedef was just a weird artifact with arbitrary semantics that were nice half the time and darn surprising the other half. We could add a flag such that Typedef!(T, supertype) that allows T as a supertype, i.e. add an alias this. There is no possibility to add implicit construction of Typedef!T from T (and that's arguably a good thing). Andrei
Nov 23 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
A late reply.


Andrei Alexandrescu:

Typedef!T is meant as a type with the same behavior as T, but 
otherwise unrelated to it.<
Right.
Allowing uncontrolled conversions to and fro is only making 
typedef weaker.<
Right, on the other hand if this type separation is handled too much strictly, the code become less handy. So probably some intermediate point is better, some conversions in controlled situations.
We could add a flag such that Typedef!(T, supertype) that allows 
T as a supertype, i.e. add an alias this.<
That in this program allows the assignments of x1 to x2 and of x2 to x1; but what is this useful for? I think this was discussed a bit in past: //----------- import std.typecons: Proxy; template Typedef(T) { alias .Typedef!(T, T.init) Typedef; } struct Typedef(T, T init, string cookie=null) { private T Typedef_payload = init; this(T init) { Typedef_payload = init; } mixin Proxy!Typedef_payload; alias Typedef_payload this; // added } void main() { alias T = Typedef!int; T x1; int x2; x1 = x2; x2 = x1; } //-----------
There is no possibility to add implicit construction of 
Typedef!T from T (and that's arguably a good thing).<
This is not very handy: void main() { import std.typecons: Typedef; alias T = Typedef!int; T[] a1 = [1, 2, 3]; // Error T[T] aa = [1:2, 3:4]; // Error import std.bigint: BigInt; BigInt[] a3 = [1, 2, 3]; // Error } Some workarounds: void main() { import std.typecons: Typedef; import std.bigint: BigInt; import std.conv: to; alias T = Typedef!int; T[] a1 = [1, 2, 3].to!(T[]); // OK BigInt[] a2 = [1, 2, 3].to!(BigInt[]); // OK auto aa1 = [1:2, 3:4].to!(T[BigInt]); // OK auto aa2 = [1:2, 3:4].to!(BigInt[T]); // OK } But it doesn't always work: import std.typecons: Typedef; import std.conv: to; alias T = Typedef!ubyte; void main() { T[] a1 = [100.T, 200.T]; // OK T[] a2 = [100, 200].to!(T[]); // Error } Bye, bearophile
Nov 30 2013
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
24-Nov-2013 00:55, bearophile пишет:
 This works if you compile with the -d switch:

 Can this situation be fixed/improved?
Use an alias? -- Dmitry Olshansky
Nov 24 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Dmitry Olshansky:

 Use an alias?
Don't be silly, please :) Bye, bearophile
Nov 24 2013