May 11, 2012
On Friday, 11 May 2012 at 20:14:29 UTC, Andrej Mitrovic wrote:
> On 5/11/12, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>> Since null is its own type now..
>
> What were the use-cases for making it a type? Seems odd to declare it:
> typeof(null) x;
>
> I mean what could you do with such a type?

It apparently implicitly converts to any pointer type (but you must cast in order to store in it...)

-=-=-
import std.stdio, std.conv;
void main() {
    typeof(null) x;
    int y = 5;
    x = cast(typeof(null)) &y;
    int * z = x;
    double * d = x; // wat
    writeln(*z);
    writeln(*d);
}
-=-=-

May 11, 2012
On Friday, 11 May 2012 at 20:14:29 UTC, Andrej Mitrovic wrote:
> What were the use-cases for making it a type?

Passing it to templates, where the type has to be inferred to something at a point where it is not yet clear what the value will actually be assigned to – without a special type for null, its implicit conversion properties would be lost. There certainly is a bug report about this, in the 5xxx range if I remember correctly.

David
May 11, 2012
On Friday, 11 May 2012 at 20:23:18 UTC, Chris Cain wrote:
> On Friday, 11 May 2012 at 20:14:29 UTC, Andrej Mitrovic wrote:
>> On 5/11/12, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>>> Since null is its own type now..
>>
>> What were the use-cases for making it a type? Seems odd to declare it:
>> typeof(null) x;
>>
>> I mean what could you do with such a type?
>
> It apparently implicitly converts to any pointer type (but you must cast in order to store in it...)
>
> -=-=-
> import std.stdio, std.conv;
> void main() {
>     typeof(null) x;
>     int y = 5;
>     x = cast(typeof(null)) &y;
>     int * z = x;
>     double * d = x; // wat
>     writeln(*z);
>     writeln(*d);
> }
> -=-=-

cast voids the warranty, especially cast(typeof(null))
May 11, 2012
On Friday, 11 May 2012 at 22:58:02 UTC, Robert DaSilva wrote:
> cast voids the warranty, especially cast(typeof(null))

To be honest, I was surprised that a black hole didn't open up and kill me for what I did.
May 11, 2012
On 05/11/2012 10:14 PM, Andrej Mitrovic wrote:
> On 5/11/12, Steven Schveighoffer<schveiguy@yahoo.com>  wrote:
>> Since null is its own type now..
>
> What were the use-cases for making it a type? Seems odd to declare it:
> typeof(null) x;
>
> I mean what could you do with such a type?


eg. IFTI.

Object x;

void foo(T)(T arg){ x = arg; }

void main(){
    foo(null);
}

This didn't work when null was of type void*.
Unfortunately, there isn't a typeof([]).
May 17, 2012
Ugh, ran into a problem again...

I was hoping I could do a type deduction for a write() function I had, based on whether the input is 'size_t' (in which case it'd be hexadecimal) or 'uint' (in which case it'd be decimal), but nope! that doesn't work. :(
	
Any chance we'll be able to distinguish aliases like these sometime?
May 17, 2012
On Thursday, May 17, 2012 02:38:13 Jonathan M Davis wrote:
> On Thursday, May 17, 2012 11:16:08 Mehrdad wrote:
> > Ugh, ran into a problem again...
> > 
> > I was hoping I could do a type deduction for a write() function I
> > had, based on whether the input is 'size_t' (in which case it'd
> > be hexadecimal) or 'uint' (in which case it'd be decimal), but
> > nope! that doesn't work. :(
> > 
> > Any chance we'll be able to distinguish aliases like these sometime?
> 
> The compiler _might_ be made to output aliases in error messages along with what they're aliased to, but it's kind of the whole point of aliases that they _not_ be their own type. So, it wouldn't make any sense to distinguish them with type deduction and the like. As it stands, as far as the compiler is concerned, there is _zero_ difference between size_t and ulong on 64-bit and size_t and uint on 32-bit. It's effectively the same as a search and replace. You obviously want something _other_ than an alias, but since size_t uses an alias, that's the way it is, and that's the way that it's bound to stay.

I'd point out though that if your problem is type deduction and compile time reflection, the code that you're generating will be generated on the architecture that it's being run on (unless you're generating .d files that you keep around for future builds), so the fact that size_t is a different size on a different machine is more or less irrelevant. You'll end up using whatever the size is for _that_ machine, which is all that it needs. The fact that it's not the same size as it might be on another machine should be irrelevant. Maybe you've found a use case where it matters, but certainly in general, I don't see why it would.

It's actually _less_ of a problem with code generation, because it can generate whatever is correct for that architecture, whereas if the programmer is doing it themselves, they can easily forget to use size_t and end up with their code not compiling properly on another architecture due to narrowing conversions and the like. Code generation just doesn't need size_t normally (if ever). It's the programmers writing code which do.

- Jonathan M Davis
May 17, 2012
On 5/17/12, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> The compiler _might_

Clang already does this with C++ for error messages, I see no reason why DMD shouldn't do the same.
May 17, 2012
On Thu, May 17, 2012 at 03:04:00PM +0200, Andrej Mitrovic wrote:
> On 5/17/12, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > The compiler _might_
> 
> Clang already does this with C++ for error messages, I see no reason why DMD shouldn't do the same.

I have brought this up before. Maybe I should open an enhancement request? GCC (g++) already does this, for example:

	/tmp/test.c:3:12: error: cannot convert ‘const char*’ to ‘CSPTR {aka int*}’ in initialization

where int* has been typedef'd to CSPTR. Note that both are shown, which is important because sometimes you need one, and sometimes the other.


T

-- 
Жил-был король когда-то, при нём блоха жила.
May 17, 2012
H. S. Teoh:

> I have brought this up before. Maybe I should open an enhancement request?

Something like this?
http://d.puremagic.com/issues/show_bug.cgi?id=5004

Bye,
bearophile