Thread overview
Dealing with type information loss in Parameters Fields and Return type
Apr 17, 2016
Nicholas Wilson
Apr 17, 2016
Anonymouse
Apr 17, 2016
Nicholas Wilson
Apr 17, 2016
Anonymouse
Apr 17, 2016
Jonathan M Davis
Apr 17, 2016
Nicholas Wilson
Apr 17, 2016
Jonathan M Davis
Apr 17, 2016
Nicholas Wilson
Apr 17, 2016
Jonathan M Davis
Apr 17, 2016
Nicholas Wilson
April 17, 2016
So currently there is a loss of information when Parameters Fields and Return type.
i.e. assuming 64 bits
size_t foo(ptrdiff_t) {};

writeln(ReturnType!foo); // prints ulong

Is there any way to get the types as (tuples of) strings of the the types as they are in the source file?

auto foos = StringReturnType!foo;
static assert(typeof(foos) == string);
pramga(msg, foos); // available at CT, prints size_t
April 17, 2016
On Sunday, 17 April 2016 at 10:12:29 UTC, Nicholas Wilson wrote:
> So currently there is a loss of information when Parameters Fields and Return type.
> i.e. assuming 64 bits
> size_t foo(ptrdiff_t) {};
>
> writeln(ReturnType!foo); // prints ulong
>
> Is there any way to get the types as (tuples of) strings of the the types as they are in the source file?
>
> auto foos = StringReturnType!foo;
> static assert(typeof(foos) == string);
> pramga(msg, foos); // available at CT, prints size_t

Correct me if I'm wrong but size_t is just an alias of ulong (assuming 64 bits), so they're the exact same thing. A rose by any other name etc.

> size_t is an alias to one of the unsigned integral basic types, and represents a type that is large enough to represent an offset into all addressible memory.
> ptrdiff_t is an alias to the signed basic type the same size as size_t.
April 17, 2016
On Sunday, 17 April 2016 at 10:22:00 UTC, Anonymouse wrote:
> On Sunday, 17 April 2016 at 10:12:29 UTC, Nicholas Wilson wrote:
>> So currently there is a loss of information when Parameters Fields and Return type.
>> i.e. assuming 64 bits
>> size_t foo(ptrdiff_t) {};
>>
>> writeln(ReturnType!foo); // prints ulong
>>
>> Is there any way to get the types as (tuples of) strings of the the types as they are in the source file?
>>
>> auto foos = StringReturnType!foo;
>> static assert(typeof(foos) == string);
>> pramga(msg, foos); // available at CT, prints size_t
>
> Correct me if I'm wrong but size_t is just an alias of ulong (assuming 64 bits), so they're the exact same thing. A rose by any other name etc.

not on 32bits its not. Also consider a Platform specific alias. The end result is that it is not portable.
April 17, 2016
On Sunday, April 17, 2016 10:12:29 Nicholas Wilson via Digitalmars-d-learn wrote:
> So currently there is a loss of information when Parameters
> Fields and Return type.
> i.e. assuming 64 bits
> size_t foo(ptrdiff_t) {};
>
> writeln(ReturnType!foo); // prints ulong
>
> Is there any way to get the types as (tuples of) strings of the the types as they are in the source file?
>
> auto foos = StringReturnType!foo;
> static assert(typeof(foos) == string);
> pramga(msg, foos); // available at CT, prints size_t

I'm actually surprised that you got the compiler to give you size_t in any form. size_t is simply an alias to either ulong (on 64-bit systems) or uint (on 32-bit systems), and for better or worse, aliases pretty much just disappear. As far as the compiler is concerned, if it sees

alias size_t = ulong;

t's basically just replacing all instances of size_t with ulong, and size_t doesn't even exist. The same goes with any other alias (like ptrdiff_t) whether you declare it or whether it's in druntime or Phobos. You will never see size_t in an error message except maybe when you mistype it, and the compiler is providing a suggestion for what you meant to type. As far as the compiler is concerned, there is no difference between an alias and what it's an alias of.

- Jonathan M Davis

April 17, 2016
On Sunday, 17 April 2016 at 10:48:08 UTC, Jonathan M Davis wrote:
> On Sunday, April 17, 2016 10:12:29 Nicholas Wilson via Digitalmars-d-learn wrote:
>> [...]
>
> I'm actually surprised that you got the compiler to give you size_t in any form. size_t is simply an alias to either ulong (on 64-bit systems) or uint (on 32-bit systems), and for better or worse, aliases pretty much just disappear. As far as the compiler is concerned, if it sees
>
> [...]

Sorry for the confusion, I didn't. getting the string "size_t" as the result of a hypothetical StringReturnType is the desired outcome.
April 17, 2016
On Sunday, April 17, 2016 11:00:15 Nicholas Wilson via Digitalmars-d-learn wrote:
> On Sunday, 17 April 2016 at 10:48:08 UTC, Jonathan M Davis wrote:
> > On Sunday, April 17, 2016 10:12:29 Nicholas Wilson via
> >
> > Digitalmars-d-learn wrote:
> >> [...]
> >
> > I'm actually surprised that you got the compiler to give you size_t in any form. size_t is simply an alias to either ulong (on 64-bit systems) or uint (on 32-bit systems), and for better or worse, aliases pretty much just disappear. As far as the compiler is concerned, if it sees
> >
> > [...]
>
> Sorry for the confusion, I didn't. getting the string "size_t" as the result of a hypothetical StringReturnType is the desired outcome.

Then I very much doubt that it's possible. The compiler doesn't distinguish between an alias and the original. As far as it's concerned, they're exactly the same thing. The compiler is pretty much doing the equivalent of textually replacing all instances of an alias with the original.

- Jonathan M Davis

April 17, 2016
On Sunday, 17 April 2016 at 11:47:52 UTC, Jonathan M Davis wrote:
> On Sunday, April 17, 2016 11:00:15 Nicholas Wilson via Digitalmars-d-learn wrote:
>> On Sunday, 17 April 2016 at 10:48:08 UTC, Jonathan M Davis wrote:
>> > [...]
>>
>> Sorry for the confusion, I didn't. getting the string "size_t" as the result of a hypothetical StringReturnType is the desired outcome.
>
> Then I very much doubt that it's possible. The compiler doesn't distinguish between an alias and the original. As far as it's concerned, they're exactly the same thing. The compiler is pretty much doing the equivalent of textually replacing all instances of an alias with the original.
>
> - Jonathan M Davis

Then time for some compiler hacking!!
April 17, 2016
On Sunday, 17 April 2016 at 10:27:10 UTC, Nicholas Wilson wrote:
> On Sunday, 17 April 2016 at 10:22:00 UTC, Anonymouse wrote:
>> On Sunday, 17 April 2016 at 10:12:29 UTC, Nicholas Wilson wrote:
>>> So currently there is a loss of information when Parameters Fields and Return type.
>>> i.e. assuming 64 bits
>>> size_t foo(ptrdiff_t) {};
>>>
>>> writeln(ReturnType!foo); // prints ulong
>>>
>>> Is there any way to get the types as (tuples of) strings of the the types as they are in the source file?
>>>
>>> auto foos = StringReturnType!foo;
>>> static assert(typeof(foos) == string);
>>> pramga(msg, foos); // available at CT, prints size_t
>>
>> Correct me if I'm wrong but size_t is just an alias of ulong (assuming 64 bits), so they're the exact same thing. A rose by any other name etc.
>
> not on 32bits its not. Also consider a Platform specific alias. The end result is that it is not portable.

"Assuming 64 bits". According to the spec as quoted, it will be "a type that is large enough to represent an offset into all addressible memory", versioned to fit the platform. So if anything, it seems to me that it is there precisely in the spirit of portability, aliasing an integer type selected to suit the platform it was compiled for. Having it be different on 32 bits is the point.

https://github.com/dlang/druntime/blob/master/src/object.d#L32

While string is likewise an alias to immutable(char)[], I think it's just specialcased to be displayed as "string" anyway in the majority of messages.


void main() {
    string foo;
    immutable(char)[] foo_alt;
    size_t bar;
    ptrdiff_t baz;
	
    assert(typeid(foo).toString == "immutable(char)[]");
    assert(typeof(foo).stringof == "string");      // <-- inconsistent
    assert(typeid(foo_alt).toString == "immutable(char)[]");
    assert(typeof(foo_alt).stringof == "string");  // <-- inconsistent-er
	
    version (D_LP64) {
        assert(typeid(bar).toString == "ulong");
        assert(typeid(baz).toString == "long");
    }
    else {
        assert(typeid(bar).toString == "uint");
        assert(typeid(baz).toString == "int");
    }
}


If you want size_t to be represented as a discrete type by that StringReturnType, I imagine you will have to specialcase size_t and ptrdiff_t in it to report them as "size_t" and "ptrdiff_t" explicitly. Bear in mind that this will clobber ulong/uint and long/int, because they really are the same.
April 17, 2016
On Sunday, April 17, 2016 12:07:45 Nicholas Wilson via Digitalmars-d-learn wrote:
> On Sunday, 17 April 2016 at 11:47:52 UTC, Jonathan M Davis wrote:
> > On Sunday, April 17, 2016 11:00:15 Nicholas Wilson via
> >
> > Digitalmars-d-learn wrote:
> >> On Sunday, 17 April 2016 at 10:48:08 UTC, Jonathan M Davis
> >>
> >> wrote:
> >> > [...]
> >>
> >> Sorry for the confusion, I didn't. getting the string "size_t" as the result of a hypothetical StringReturnType is the desired outcome.
> >
> > Then I very much doubt that it's possible. The compiler doesn't distinguish between an alias and the original. As far as it's concerned, they're exactly the same thing. The compiler is pretty much doing the equivalent of textually replacing all instances of an alias with the original.
> >
> > - Jonathan M Davis
>
> Then time for some compiler hacking!!

Perhaps, but be aware that Walter Bright thinks that size_t should stay as-is:

http://forum.dlang.org/post/nevrsb$2ge1$1@digitalmars.com

Maybe some sort of general change to how aliases work would be acceptable and would give you what you want. I don't know. But he's against special casing stuff like size_t.

- Jonathan M Davis

April 17, 2016
On Sunday, 17 April 2016 at 13:56:38 UTC, Jonathan M Davis wrote:
> Perhaps, but be aware that Walter Bright thinks that size_t should stay as-is:
>
> http://forum.dlang.org/post/nevrsb$2ge1$1@digitalmars.com
>
> Maybe some sort of general change to how aliases work would be acceptable and would give you what you want. I don't know. But he's against special casing stuff like size_t.
>
> - Jonathan M Davis

I was just going to make a __traits that returns a tuple of string lf the types as seen by the parser (i.e. "size_t"). While size_t and ptrdiff_t are the most common case they are not special. e.g.
version = B;
version(B)
{
    struct b{}
    alias A = b*;
}
version(C)
{
    struct c{}
    alias A = c*;
}
void foo(A a){}
writeln(Parameters!foo);//prints b*
writeln(__traits(whatevericallit,foo);// prints A