www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why typedef's shouldn't have been removed :(

reply "Mehrdad" <wfunction hotmail.com> writes:
Now it's impossible to figure out whether a ParameterTypeTuple 
contains an HWND versus an HGDIOBJ or whatever...

this should really be fixed...
May 04 2012
next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 5 May 2012 at 05:02:48 UTC, Mehrdad wrote:
 Now it's impossible to figure out whether a ParameterTypeTuple 
 contains an HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

Features like this: typedef int type = 5; type var; var.init; // is 5 AFAIK are also lost.
May 04 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
And for those who couldn't care less about Windows, I should also 
note that it's impossible to distinguish between size_t and uint, 
etc.

On Saturday, 5 May 2012 at 05:25:29 UTC, Maxim Fomin wrote:
 On Saturday, 5 May 2012 at 05:02:48 UTC, Mehrdad wrote:
 Now it's impossible to figure out whether a ParameterTypeTuple 
 contains an HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

Features like this: typedef int type = 5; type var; var.init; // is 5 AFAIK are also lost.

May 04 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
(Sorry that wasn't meant to be directed at you, I just happened
to click reply on your post)

On Saturday, 5 May 2012 at 05:25:29 UTC, Maxim Fomin wrote:
 On Saturday, 5 May 2012 at 05:02:48 UTC, Mehrdad wrote:
 Now it's impossible to figure out whether a ParameterTypeTuple 
 contains an HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

Features like this: typedef int type = 5; type var; var.init; // is 5 AFAIK are also lost.

May 04 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Mehrdad:
 Now it's impossible to figure out whether a ParameterTypeTuple 
 contains an HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

typedef is a quite useful feature, but the one present in D was unsound/broken, especially in presence of OOP. Fixing language features is hard (people didn't seem to understand that typedef is not meant to be used with classes), once their semantics is defined, it's quite hard to fix it. But adding features to D/Phobos is much simpler. So once there is a clear and sound design for what this feature has to do and its semantics, I expect to see in D a way to do the same things. Currently the Typedef in Phobos is more broken than the built-in typedef. Here the Ada language is a good reference to copy from. So the idea of removing typedef was good iff we eventually have something good to replace it. Bye, bearophile
May 05 2012
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2012-05-05 05:02:44 +0000, "Mehrdad" <wfunction hotmail.com> said:

 Now it's impossible to figure out whether a ParameterTypeTuple contains 
 an HWND versus an HGDIOBJ or whatever...
 
 this should really be fixed...

It should be fixed indeed. Perhaps HWND should be defined more like this: struct HWND { void *handle; } Or if you want it to implement some kind of inheritance scheme: struct HANDLE { void *ptr; } struct HWND { HANDLE handle; alias handle this; } That's still a lot better than typedef since you can control what operations are allowed on the type. For instance, you can't multiply two handles with the struct definition, with typedef you could. My only fear is that this might not work play well with the C calling convention (or Window's in this case). If that's the case, then it's a good argument for having a separate language construct. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
May 05 2012
next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2012-05-05 18:20:44 +0000, "Mehrdad" <wfunction hotmail.com> said:

 How do you fix it for size_t and uint, etc.?

I'm not sure what problem you're seeing. You can do the same with any type. struct PineappleSize { size_t size; } If you need operators to work, define them. If you need the new type to be a specialization, just use alias this. Something simple: struct PineappleSize { size_t size; alias size this; PineappleSize opBinary(string op)(PineappleSize other) { mixin("return size "~op~" other.size"); } } -- Michel Fortin michel.fortin michelf.com http://michelf.com/
May 06 2012
prev sibling next sibling parent reply mta`chrono <chrono mta-international.net> writes:
Am 08.05.2012 16:03, schrieb bearophile:
 Steven Schveighoffer:
 
 But making std.typecons.TypeDef work *is* a valid path to get what you
 want (typedefs that work like they used to).  If that isn't possible,
 let's fix the language constructs that are blocking it!

Right. Bye, bearophile

Maybe it's not directly related to this topic, but shouldn't that be rather part of druntime?
May 08 2012
parent reply mta`chrono <chrono mta-international.net> writes:
 Maybe it's not directly related to this topic, but shouldn't that be
 rather part of druntime?

Only if something else in druntime needs it, which it doesn't. - Jonathan M Davis

There is a real trend to purify the language. I also think it's the right decision to replace compiler intrinsics / language feature with their library counterparts. Moving stuff to phobos is fine as long as you use phobos. But I'm using tango and druntime. I haven't even installed phobos on my system. The same impacts deimos. People tend to create unneccessary phobos dependencys.
May 09 2012
parent mta`chrono <chrono mta-international.net> writes:
Am 09.05.2012 11:53, schrieb Jonathan M Davis:
 On Wednesday, May 09, 2012 10:00:37 mta`chrono wrote:
 Maybe it's not directly related to this topic, but shouldn't that be
 rather part of druntime?

Only if something else in druntime needs it, which it doesn't. - Jonathan M Davis

There is a real trend to purify the language. I also think it's the right decision to replace compiler intrinsics / language feature with their library counterparts. Moving stuff to phobos is fine as long as you use phobos. But I'm using tango and druntime. I haven't even installed phobos on my system. The same impacts deimos. People tend to create unneccessary phobos dependencys.

In general, we're not sticking anything in druntime unless it needs to be there. It's also pretty much expected that projects will use Phobos. druntime isn't even provided at a separate library when distributed with dmd. If you're specifically trying to avoid using Phobos, you can do that, but don't expect stuff that doesn't need to be in druntime to be put into druntime just because you don't want to use D's standard library. Since Phobos is statically linked at this point, the parts that you don't use wouldn't be pulled in anyway. But you can also copy it from Phobos and put it in your project if you want to (as long as it doesn't have a lot of other dependencies in Phobos).

It's nothing more than a general design decision what belongs into druntime and what doesn't. I don't expect you to do anything just because I say so (Don't believe me!), but since this newsgroup is open for everybody to post his/her crap, I'll do similar. ;-) The question I had to came is across is "What is druntime?". It provides D's _meat and potatoes_ used for _fundamental_ features of the language like garbage collecting, threads, synchronisation and it's even used for array manipulation. Coding D without druntime is not possible. Sooner or later dmd will be able to support ARM android or iOS. And then we'll be lucky to only port druntime to the new plattform. Phobos is a really powerfull library but it's too fat with all it's dependencies. (libcurl is one of it). The reason why C is so powerfull and runs even on a tiny 1,59 €uro AVR processor is quite simple. It's _NOT_ too much coupled to any standard library. There are hundreads glibc, uClibc, bionic, diet libc. just to mention a few.
 Personally, I don't know how you could get by without using Phobos for at 
 least std.traits unless you avoid templates (which would _really_ be reducing 
 D's power - I'd hate to use D without templates), since it's a _lot_ harder to 
 have good template constraints without std.traits.

That's how I do for now: Copying std.traits to tango.core.Traits. It works quite fine unless you start using tango and phobos side by side in a "hybrid" project. That's why I prefer a common core.traits.
 
 - Jonathan M Davis

Okay, now you got my 50 Cents. Thanks for reading.
May 09 2012
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
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 11 2012
prev sibling next sibling parent Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
mixin template TypeDef(Type, string name, Type init)
{
    mixin(`struct `~name~` { public alias _impl this; private Type
_impl = init; };`);
}

unittest
{
    mixin TypeDef!(int, `MyInt`, 5);

    MyInt mi;

    assert(typeid(myInt) != typeid(int));
    assert(mi == 5);
}

On Sat, May 5, 2012 at 3:09 PM, bearophile <bearophileHUGS lycos.com> wrote:
 Mehrdad:

 Now it's impossible to figure out whether a ParameterTypeTuple contains an
 HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

typedef is a quite useful feature, but the one present in D was unsound/broken, especially in presence of OOP. Fixing language features is hard (people didn't seem to understand that typedef is not meant to be used with classes), once their semantics is defined, it's quite hard to fix it. But adding features to D/Phobos is much simpler. So once there is a clear and sound design for what this feature has to do and its semantics, I expect to see in D a way to do the same things. Currently the Typedef in Phobos is more broken than the built-in typedef. Here the Ada language is a good reference to copy from. So the idea of removing typedef was good iff we eventually have something good to replace it. Bye, bearophile

-- Bye, Gor Gyolchanyan.
May 05 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
How do you fix it for size_t and uint, etc.?

On Saturday, 5 May 2012 at 13:01:08 UTC, Michel Fortin wrote:
 On 2012-05-05 05:02:44 +0000, "Mehrdad" <wfunction hotmail.com> 
 said:

 Now it's impossible to figure out whether a ParameterTypeTuple 
 contains an HWND versus an HGDIOBJ or whatever...
 
 this should really be fixed...

It should be fixed indeed. Perhaps HWND should be defined more like this: struct HWND { void *handle; } Or if you want it to implement some kind of inheritance scheme: struct HANDLE { void *ptr; } struct HWND { HANDLE handle; alias handle this; } That's still a lot better than typedef since you can control what operations are allowed on the type. For instance, you can't multiply two handles with the struct definition, with typedef you could. My only fear is that this might not work play well with the C calling convention (or Window's in this case). If that's the case, then it's a good argument for having a separate language construct.

May 05 2012
prev sibling next sibling parent Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
See my version.

On Sat, May 5, 2012 at 10:20 PM, Mehrdad <wfunction hotmail.com> wrote:
 How do you fix it for size_t and uint, etc.?


 On Saturday, 5 May 2012 at 13:01:08 UTC, Michel Fortin wrote:
 On 2012-05-05 05:02:44 +0000, "Mehrdad" <wfunction hotmail.com> said:

 Now it's impossible to figure out whether a ParameterTypeTuple contains
 an HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

It should be fixed indeed. Perhaps HWND should be defined more like this=


 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct HWND { void *handle; }

 Or if you want it to implement some kind of inheritance scheme:

 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct HANDLE { void *ptr; }
 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct HWND { HANDLE handle; alias handle thi=


 That's still a lot better than typedef since you can control what
 operations are allowed on the type. For instance, you can't multiply two
 handles with the struct definition, with typedef you could.

 My only fear is that this might not work play well with the C calling
 convention (or Window's in this case). If that's the case, then it's a g=


 argument for having a separate language construct.


--=20 Bye, Gor Gyolchanyan.
May 05 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
The one with TypeDef?

That's not how it's defined though.

On Saturday, 5 May 2012 at 18:31:44 UTC, Gor Gyolchanyan wrote:
 See my version.

May 05 2012
prev sibling next sibling parent Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
The effect is the same. You have a new type with a new init, that
behaves the same way.

On Sat, May 5, 2012 at 10:38 PM, Mehrdad <wfunction hotmail.com> wrote:
 The one with TypeDef?

 That's not how it's defined though.

 On Saturday, 5 May 2012 at 18:31:44 UTC, Gor Gyolchanyan wrote:
 See my version.


-- Bye, Gor Gyolchanyan.
May 05 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
Er, the point is, there are functions ALREADY using size_t, and I 
need to figure out which parameters those are.

On Saturday, 5 May 2012 at 18:42:05 UTC, Gor Gyolchanyan wrote:
 The effect is the same. You have a new type with a new init, 
 that
 behaves the same way.

 On Sat, May 5, 2012 at 10:38 PM, Mehrdad 
 <wfunction hotmail.com> wrote:
 The one with TypeDef?

 That's not how it's defined though.

 On Saturday, 5 May 2012 at 18:31:44 UTC, Gor Gyolchanyan wrote:
 See my version.



May 05 2012
prev sibling next sibling parent Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
well, there's no solution to it of the alias is in use, no matter what
alternatives are.

On Sat, May 5, 2012 at 10:43 PM, Mehrdad <wfunction hotmail.com> wrote:
 Er, the point is, there are functions ALREADY using size_t, and I need to
 figure out which parameters those are.


 On Saturday, 5 May 2012 at 18:42:05 UTC, Gor Gyolchanyan wrote:
 The effect is the same. You have a new type with a new init, that
 behaves the same way.

 On Sat, May 5, 2012 at 10:38 PM, Mehrdad <wfunction hotmail.com> wrote:
 The one with TypeDef?

 That's not how it's defined though.

 On Saturday, 5 May 2012 at 18:31:44 UTC, Gor Gyolchanyan wrote:
 See my version.




-- Bye, Gor Gyolchanyan.
May 05 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
One solution is to bring back typedef, at least for non-classes 
and non-interfaces.

Another is to change the definition of size_t.

Neither of which anyone except the compiler/library developers 
can fix.


On Saturday, 5 May 2012 at 18:52:57 UTC, Gor Gyolchanyan wrote:
 well, there's no solution to it of the alias is in use, no 
 matter what
 alternatives are.

May 05 2012
prev sibling next sibling parent "Chris Cain" <clcain uncg.edu> writes:
On Saturday, 5 May 2012 at 18:43:41 UTC, Mehrdad wrote:
 Er, the point is, there are functions ALREADY using size_t, and 
 I need to figure out which parameters those are.

Out of curiosity, why would you need to "know" which parameters are size_t? True, size_t is either uint or ulong and you can't really know for sure if you have a uint or ulong and it was actually a size_t ... but why would you need to know?
May 05 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
That's *such* a lame question...

Even if I _couldn't_ tell you a reason, that'd still be a lame
question, because the *entire point* of reflection is to access
type information information about the program... if for nothing
other than printing it out for the user.

But it's more than that: it's the same darn reason why you need
to distinguish between
void* and HWND -- it's an ERROR!

In other words, this must NOT compile!

auto call(F, T...)(F func, T args) { return func(args); }
void test(uint) { }
void main() { call!(typeof(&test), size_t)(&test, 1); }

If you're still asking "why shouldn't it compile" then you should
look up what "type safety" means.


On Saturday, 5 May 2012 at 21:24:50 UTC, Chris Cain wrote:
 On Saturday, 5 May 2012 at 18:43:41 UTC, Mehrdad wrote:
 Er, the point is, there are functions ALREADY using size_t, 
 and I need to figure out which parameters those are.

Out of curiosity, why would you need to "know" which parameters are size_t? True, size_t is either uint or ulong and you can't really know for sure if you have a uint or ulong and it was actually a size_t ... but why would you need to know?

May 05 2012
prev sibling next sibling parent "Matt Peterson" <ricochet1k gmail.com> writes:
On Saturday, 5 May 2012 at 23:41:52 UTC, Mehrdad wrote:
 That's *such* a lame question...

 Even if I _couldn't_ tell you a reason, that'd still be a lame
 question, because the *entire point* of reflection is to access
 type information information about the program... if for nothing
 other than printing it out for the user.

 But it's more than that: it's the same darn reason why you need
 to distinguish between
 void* and HWND -- it's an ERROR!

 In other words, this must NOT compile!

 auto call(F, T...)(F func, T args) { return func(args); }
 void test(uint) { }
 void main() { call!(typeof(&test), size_t)(&test, 1); }

 If you're still asking "why shouldn't it compile" then you 
 should
 look up what "type safety" means.

That doesn't compile on x86_64. The point of size_t is to be the native word-sized integer for the platform, and it does exactly that.
May 05 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
 The point of size_t is to be the native word-sized integer for 
 the platform

"Native word-sized integer" is such a blurry term, but of course you wouldn't know this without understanding why C has a gazillion "native" integer types... (hint: if you're trying to justify these with today's x86 processors, you're already on the wrong track) The point of size_t is for it to be able to represent the size of something. That's all. The point of sizediff_t is for it to be able to represent the difference between two size_t's. That's all. The point of ptrdiff_t is for it to be able to represent the difference between two pointers. That's all. Those three need NOT be the same size on the same machine, and they need NOT be the same as the "fastest" integers on any platform. That's the whole point of std.stdint, in case you hadn't heard of it.
 That doesn't compile on x86_64.

I can't tell if you're missing my point or what... In case that was unclear: ***** I'm saying that shouldn't compile on *ANY* platform. **** What you're saying is like saying "dchar[] function()" should be interchangeable with "uint[] function()" just because they're the same data on the same platform. Or like saying class Bar { } and class Foo { } should be interchangeable because there's no actual difference between them. Or like saying "HWND function()" and "HANDLE function()" and "void* function()" should be interchangeable because they're all the same anyway. Kind of silly IMO.
May 05 2012
prev sibling next sibling parent "Matt Peterson" <ricochet1k gmail.com> writes:
I understand you're frustrated, but you don't need to be so
hostile. I agree with most of what you've said on this thread.
And just because I made a short comment doesn't mean I don't know
about std.stdint, sizediff_t, etc. My point was to say that
size_t is supposed to be the size of the architecture's word. I
said nothing about it being the "fastest" type or even whether it
was useful . I would be very interested if you have a better
solution for the integer typing/naming problem.

There definitely needs to be way to define a type that can't
implicitly cast to its base type. The problem is that the
original typedef did do implicit casting away, and that has
potential to cause confusion when porting from C or D1. I don't
see that as much of a problem, but others might.




On Sunday, 6 May 2012 at 02:25:54 UTC, Mehrdad wrote:
 The point of size_t is to be the native word-sized integer for 
 the platform

"Native word-sized integer" is such a blurry term, but of course you wouldn't know this without understanding why C has a gazillion "native" integer types... (hint: if you're trying to justify these with today's x86 processors, you're already on the wrong track) The point of size_t is for it to be able to represent the size of something. That's all. The point of sizediff_t is for it to be able to represent the difference between two size_t's. That's all. The point of ptrdiff_t is for it to be able to represent the difference between two pointers. That's all. Those three need NOT be the same size on the same machine, and they need NOT be the same as the "fastest" integers on any platform. That's the whole point of std.stdint, in case you hadn't heard of it.
 That doesn't compile on x86_64.

I can't tell if you're missing my point or what... In case that was unclear: ***** I'm saying that shouldn't compile on *ANY* platform. **** What you're saying is like saying "dchar[] function()" should be interchangeable with "uint[] function()" just because they're the same data on the same platform. Or like saying class Bar { } and class Foo { } should be interchangeable because there's no actual difference between them. Or like saying "HWND function()" and "HANDLE function()" and "void* function()" should be interchangeable because they're all the same anyway. Kind of silly IMO.

May 05 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Sunday, 6 May 2012 at 03:15:01 UTC, Matt Peterson wrote:
 I understand you're frustrated, but you don't need to be so 
 hostile.

You're completely right... I apologize about that, it was completely my fault. I've indeed been pretty frustrated at this typedef nonsense (and the like), since it's made something otherwise elegant become something very annoying and time-wasting. To Chris Cain as well, my response there was rather hostile too -- my apologies about that as well.
 I agree with most of what you've said on this thread. And just 
 because I made a short comment doesn't mean I don't know about 
 std.stdint, sizediff_t, etc. My point was to say that size_t is 
 supposed to be the size of the architecture's word. I said 
 nothing about it being the "fastest" type or even whether it 
 was useful . I would be very interested if you have a better 
 solution for the integer typing/naming problem.

Right, but what I was saying was that that *isn't* what it's meant to be! It's just a *size* type, not a *word* of any kind... (think about systems with interleaving pointers, for example, x86 with segmentation -- the notion of a "word" isn't so obvious anymore, when denoting sizes)
 There definitely needs to be way to define a type that can't 
 implicitly cast to its base type. The problem is that the 
 original typedef did do implicit casting away, and that has 
 potential to cause confusion when porting from C or D1. I don't 
 see that as much of a problem, but others might.

Yeah, I still don't understand what the "potential to cause confusion" was. Was it *actually* causing a significant problem, or was it just a "potential" problem?
May 05 2012
prev sibling next sibling parent "Matt Peterson" <ricochet1k gmail.com> writes:
On Sunday, 6 May 2012 at 03:28:32 UTC, Mehrdad wrote:
 Right, but what I was saying was that that *isn't* what it's 
 meant to be! It's just a *size* type, not a *word* of any 
 kind... (think about systems with interleaving pointers, for 
 example, x86 with segmentation -- the notion of a "word" isn't 
 so obvious anymore, when denoting sizes)

Yeah, figuring out what to name something is always a challenge, and the huge variety and complexity of modern, and even not-so-modern processors doesn't help at all.
 There definitely needs to be way to define a type that can't 
 implicitly cast to its base type. The problem is that the 
 original typedef did do implicit casting away, and that has 
 potential to cause confusion when porting from C or D1. I 
 don't see that as much of a problem, but others might.

Yeah, I still don't understand what the "potential to cause confusion" was. Was it *actually* causing a significant problem, or was it just a "potential" problem?

The issue is if someone new to D2 is porting code from C or D1, they would get all kinds of weird errors caused by using typedef instead of D2's alias and trying to do math or expecting implicit casting to work. But D2 is a different language, with different syntax and semantics. Anyone expecting copied C to "just work" in D2 is expecting a miracle, but that's not to say we can't try to make it as easy as possible. IMO, alias is a much better name than typedef, which is quite generic because technically any struct, class, or even function declaration is defining a new type. But adding a new keyword is ugly, assuming you can think of a good one, so typedef is probably the best choice. The only other alternative is reusing existing keywords, but I can't even think of a good choice. Does any of static/const/immutable/etc. alias sound good to anyone?
May 05 2012
prev sibling next sibling parent "Chris Cain" <clcain uncg.edu> writes:
On Sunday, 6 May 2012 at 03:28:32 UTC, Mehrdad wrote:
 To  Chris Cain as well, my response there was rather hostile 
 too -- my apologies about that as well.

It's OK. The only reason I was asking is because I may have been able to offer you a better alternative to what you're actually trying to accomplish, because it seems like to me you're always trying to code C++ in D.
May 06 2012
prev sibling next sibling parent "Chris Cain" <clcain uncg.edu> writes:
On Saturday, 5 May 2012 at 23:41:52 UTC, Mehrdad wrote:
 Even if I _couldn't_ tell you a reason, that'd still be a lame
 question, because the *entire point* of reflection is to access
 type information information about the program... if for nothing
 other than printing it out for the user.

Also, just as a heads up: If you want language features to be added (or re-added in this case), saying "I shouldn't have to give a reason" is an extremely bad way to start. You should look through a lot of old threads. Even when people sometimes give some relatively incredible reasons (at least, IMO) for why something should be done, Walter Bright and Andrei Alexandrescu will disagree with adding it to the language. There's at least two good reasons why: 1. D is already pretty complex (and can do almost way too much stuff). In fact most of what you want could easily added via Phobos ("type safety" of types OTHER than size_t) because of that power. 2. You're not actually arguing whether a language feature should be added. You're arguing why your language feature should be prioritized above all the other things in the queue (such as bug fixes). When it comes down to it, which do you think is more important? A bug which prevents valid code from compiling (or, worse, silently producing the wrong result) ... or a language feature that, for the most part, can be implemented in Phobos in three to five lines of code whose reason for existing is "I shouldn't have to give a reason"?
 But it's more than that: it's the same darn reason why you need
 to distinguish between
 void* and HWND -- it's an ERROR!

I'd agree, but you have a solution for that now.
 In other words, this must NOT compile!

 auto call(F, T...)(F func, T args) { return func(args); }
 void test(uint) { }
 void main() { call!(typeof(&test), size_t)(&test, 1); }

 If you're still asking "why shouldn't it compile" then you 
 should
 look up what "type safety" means.

Please don't put words into my mouth :) In this case, the definition of size_t is made with an alias, so via alias semantics, this will compile on x86 but not on x86-64. It's rather surprising the first few times you do this if you're being careless. In terms of type safety, I can see your point. I'd be holding back if I didn't say that when I started learning D a couple of months ago I got in the habit of compiling in both 32-bit and 64-bit Linux to figure out if I was using size_t in the right places. At this point, I don't make the mistake anymore, but I wouldn't be surprised that it doesn't make things more difficult in the long run as more people start using D. However, ultimately, I have to ask if this is what you're doing (trying to make your code size_t "type safe"), or are you just trying to get typedef back so you can use that instead of learning how to do what you want the current D-way? Because it's going to take much longer and take a lot more effort for you to change D into C++ rather than just learning the way D is right now. Especially if people keep giving reasonable approaches for how you can do what you want in current D.
May 06 2012
prev sibling next sibling parent reply "John Campbell" <je campbe.ll> writes:
On Saturday, 5 May 2012 at 05:02:48 UTC, Mehrdad wrote:
 Now it's impossible to figure out whether a ParameterTypeTuple 
 contains an HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

Since I don't see it discussed in this thread: Which problems do you have with http://dlang.org/phobos/std_typecons.html#Typedef? John
May 06 2012
parent mta`chrono <chrono mta-international.net> writes:
Am 06.05.2012 14:22, schrieb John Campbell:
 On Saturday, 5 May 2012 at 05:02:48 UTC, Mehrdad wrote:
 Now it's impossible to figure out whether a ParameterTypeTuple
 contains an HWND versus an HGDIOBJ or whatever...

 this should really be fixed...

Since I don't see it discussed in this thread: Which problems do you have with http://dlang.org/phobos/std_typecons.html#Typedef? John

There are a lot of people using D as a better C. Templatisation of every language keyword in conjunction with forcing the user to have phobos dependency is a real _PAIN_.
May 07 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Sunday, 6 May 2012 at 12:04:52 UTC, Chris Cain wrote:
 Also, just as a heads up: If you want language features to be 
 added (or re-added in this case), saying "I shouldn't have to 
 give a reason" is an extremely bad way to start. You should 
 look through a lot of old threads. Even when people sometimes 
 give some relatively incredible reasons (at least, IMO) for why 
 something should be done, Walter Bright and Andrei Alexandrescu 
 will disagree with adding it to the language.

Well, it's not *quite* like I was saying "I shouldn't have to give a reason". Rather, I was saying that, when you're doing reflection, you should have access to all information, even if it looks useless.
 There's at least two good reasons why:
 1. D is already pretty complex (and can do almost way too much 
 stuff). In fact most of what you want could easily added via 
 Phobos ("type safety" of types OTHER than size_t) because of 
 that power.
 2. You're not actually arguing whether a language feature 
 should be added. You're arguing why your language feature 
 should be prioritized above all the other things in the queue 
 (such as bug fixes).

I *wasn't* saying my issue was above the bug fixes... I'm not sure where you got that impression. I was just saying it needs to be somewhere in the queue.
 When it comes down to it, which do you think is more important? 
 A bug which prevents valid code from compiling (or, worse, 
 silently producing the wrong result) ... or a language feature 
 that, for the most part, can be implemented in Phobos in three 
 to five lines of code whose reason for existing is "I shouldn't 
 have to give a reason"?

Again, I wasn't saying it's /more/ important than anything...
 But it's more than that: it's the same darn reason why you need
 to distinguish between
 void* and HWND -- it's an ERROR!

I'd agree, but you have a solution for that now.

Not for the built-in types though.
 In other words, this must NOT compile!

 auto call(F, T...)(F func, T args) { return func(args); }
 void test(uint) { }
 void main() { call!(typeof(&test), size_t)(&test, 1); }

 If you're still asking "why shouldn't it compile" then you 
 should
 look up what "type safety" means.

Please don't put words into my mouth :) In this case, the definition of size_t is made with an alias, so via alias semantics, this will compile on x86 but not on x86-64. It's rather surprising the first few times you do this if you're being careless. In terms of type safety, I can see your point.

Yeah that *is* my point, lol.
 However, ultimately, I have to ask if this is what you're doing 
 (trying to make your code size_t "type safe"), or are you just 
 trying to get typedef back so you can use that instead of 
 learning how to do what you want the current D-way?

I'm giving *multiple* reasons for getting 'typedef' back: 1. Type safety. 2. Reflection should be able to get alias information. Asking "why" is silly... it's reflection. 3. The current suggested use of alias as an "alternative" to typedef makes things worse due to all the implicit assignments that they allow in your code. - IMHO using 'alias' instead of 'typedef' is a *BUG* (no, I'm not just referring to HANDLE; yes, that includes size_t), since it allows assignments that shouldn't be able to take place on ANY platform (without a cast).
 Because it's going to take much longer and take a lot more 
 effort for you to change D into C++ rather than just learning 
 the way D is right now.

I'm not sure where you got the idea of C++ from. C++ doesn't even _have_ reflection, and it treats typedefs pretty much the same as D does right now...
 Especially if people keep giving reasonable approaches for how 
 you can do what you want in current D.

You're missing the problem: (1) I'm saying function(size_t) and function(uint) are different functions, and people are telling me that's silly, who cares about the type anyway. That's not an 'alternative'. (2) I'm saying function(void*) and function(HANDLE) are different functions, and people are telling me to use TypeDef. Which is of course an alternative, except that it requires me to modify the source code of my library. (Which, by the way, goes against the concept of dynamic linking, which IMHO is another problem. But I guess that'll only be an issue when D supports dynamic linking correctly...) I would be more inclined to agree with those reasons (1) and (2) were the same reason, but they aren't! So what that tells me is that people are just giving random reasons for not adding back typedef, without actually thinking about the implications. (I'm pretty sure none of the people who suggested using TypeDef for HWND realized that we'd have to do the same thing for size_t and such. Otherwise, when I'd have asked about that, the response wouldn't have been "who cares".)
May 06 2012
prev sibling next sibling parent "Chris Cain" <clcain uncg.edu> writes:
On Sunday, 6 May 2012 at 14:58:53 UTC, Mehrdad wrote:
 Well, it's not *quite* like I was saying "I shouldn't have to 
 give a reason".
 Rather, I was saying that, when you're doing reflection, you 
 should have access to all information, even if it looks useless.

I understand that, I was just stating that you shouldn't start off your post by saying "even if I couldn't tell you a reason" and explained why that's generally a bad way to start.
 I *wasn't* saying my issue was above the bug fixes... I'm not 
 sure where you got that impression. I was just saying it needs 
 to be somewhere in the queue.

I was just stating that the effort to implement the changes you want has to come from somewhere. There's no such thing as a free lunch. To do anything, you have to give something else up. This is standard "opportunity cost". So, by saying you want this done, you've implicitly said that it's more important than something else... to figure out where in the queue it needs to go requires reasons. To even put it in the queue requires reasons too (because otherwise the list would become completely unmanageable at some point). I'm not even the person you have to convince, but I would think it would help you to outline the reasons why things need to be changed and the benefits. And it seems you have to the best of your ability, so hopefully that'll get your request noticed by someone else.
 (1) I'm saying function(size_t) and function(uint) are 
 different functions, and people are telling me that's silly, 
 who cares about the type anyway. That's not an 'alternative'.

I'm not sure if people are really saying that's silly... It's more like where in your code does it matter so that we can suggest alternatives. If we don't know what you're trying to do, we can't actually suggest the 'alternative' we're talking about. Our alternative isn't to call it silly, we're trying to get where you're coming from (and we couldn't see a reason why you need it because _you hadn't told us yet_). We're just trying to communicate here, we're not trying to belittle you or your ideas. You said you needed a typedef to do x, we suggest alternative that does x. Then you say well, what about y and we don't have an answer for y, but I'm trying to get you going by providing you a different way of looking at the problem so that y doesn't even matter. But without knowing the problem, I certainly can't offer a solution... I really wanted to help you get whatever you want done in D, but apparently I can't (or at least, if I could, I can't say I want to enough to keep trying to discover what you're trying to do), so all I can do is wish you good luck.
May 06 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 5/6/12, John Campbell <je campbe.ll> wrote:
 Since I don't see it discussed in this thread: Which problems do
 you have with http://dlang.org/phobos/std_typecons.html#Typedef?

Here's one: struct Class { mixin CompositeFields; SymID[] baseIDs; // indexed base class IDs } alias std.typecons.Typedef!Class Struct; D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(3030): Error: struct dgen.types.Class no size yet for forward reference Another problem is generics. I've got a function that creates a string mixin. It returns hash fields with various value types, e.g. it generates code like this: File[string] FileMap; Namespace[string] NamespaceMap; Class[string] ClassMap; It basically generates the name of each field like so: %s[string] %sMap Where %s is the type name, picked up by either .stringof or to!string(). However it can't pick up the name of the alias itself, the hash field for the Struct type would end up looking like this: Typedef!(Class,Class(null))[string] Typedef!(Class,Class(null))Map; That's an invalid field name there ("Typedef!(Class,Class(null))Map"). What I really need is the name of the alias itself, so it would pick "Struct" from here: alias std.typecons.Typedef!Class Struct; and generate the field as: Struct[string] StructMap; A workaround is to have a mangle function. Since I use a helper function to access individual fields the name of the fields doesn't matter much so mangling would be ok for my needs. But even though there's a demangle function in druntime, there's no mangle function..
May 06 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 06 May 2012 10:58:52 -0400, Mehrdad <wfunction hotmail.com> wrote:

 You're missing the problem:

 (1) I'm saying function(size_t) and function(uint) are different  
 functions, and people are telling me that's silly, who cares about the  
 type anyway. That's not an 'alternative'.

No, they are the same function. size_t is aliased to uint. What *you* want size_t to mean is not what it is, it's an alias to the word-sized unsigned integer on a platform. Get used to it, use another type if you don't want it to be that. It's the same in C/C++ BTW. D's alias === C's typedef, and C's size_t is a typedef.
 (2) I'm saying function(void*) and function(HANDLE) are different  
 functions, and people are telling me to use TypeDef. Which is of course  
 an alternative, except that it requires me to modify the source code of  
 my library.

Wait, you have to modify one type definition, right? Is that really not satisfactory? I don't understand this line of reasoning.
 I would be more inclined to agree with those reasons (1) and (2) were  
 the same reason, but they aren't!

 So what that tells me is that people are just giving random reasons for  
 not adding back typedef, without actually thinking about the  
 implications.

I can't say I ever used typedef when it was allowed. I can see how it can be useful in certain situations, but I think the path is available to make an equivalent library solution work (it seems several people have said it doesn't, why not spend time trying to fix it rather than complaining about features that aren't coming back?)
 (I'm pretty sure none of the people who suggested using TypeDef for HWND  
 realized that we'd have to do the same thing for size_t and such.  
 Otherwise, when I'd have asked about that, the response wouldn't have  
 been "who cares".)

I think they didn't realize it because it's completely false ;) You saying it's not false doesn't make it any more true. -Steve
May 07 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Monday, 7 May 2012 at 12:18:36 UTC, Steven Schveighoffer wrote:
 No, they are the same function.  size_t is aliased to uint.  
 What *you* want size_t to mean is not what it is, it's an alias 
 to the word-sized unsigned integer on a platform.  Get used to 
 it, use another type if you don't want it to be that.

No kidding! I use a different language altogether when I don't like D. That doesn't tell me anything useful though...
 It's the same in C/C++ BTW.  D's alias === C's typedef, and C's 
 size_t is a typedef.

Did you read my own response to someone else? You're telling me something I already mentioned myself... My response: "C++ doesn't even _have_ reflection, and it treats typedefs pretty much the same as D does right now..."
 (2) I'm saying function(void*) and function(HANDLE) are 
 different functions, and people are telling me to use TypeDef. 
 Which is of course an alternative, except that it requires me 
 to modify the source code of my library.

Wait, you have to modify one type definition, right? Is that really not satisfactory? I don't understand this line of reasoning.

No, it's not satisfactory, because I'm not always in control of the type definition.
 I can't say I ever used typedef when it was allowed.

That doesn't make it useless. :P
 I can see how it can be useful in certain situations, but I 
 think the path is available to make an equivalent library 
 solution work (it seems several people have said it doesn't, 
 why not spend time trying to fix it rather than complaining 
 about features that aren't coming back?)

Um... if people don't agree that size_t should be a different type, why would I spend time 'fixing' something that won't be used anyway?
 (I'm pretty sure none of the people who suggested using 
 TypeDef for HWND realized that we'd have to do the same thing 
 for size_t and such. Otherwise, when I'd have asked about 
 that, the response wouldn't have been "who cares".)

I think they didn't realize it because it's completely false ;) You saying it's not false doesn't make it any more true.

It might have been false, but if so, that falsehood definitely wasn't communicated. So from my perspective, it's true. (I don't have ESP to figure out what people *really* think of, sorry... and no pun intended :P)
May 07 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 07 May 2012 12:10:20 -0400, Mehrdad <wfunction hotmail.com> wrote:

 On Monday, 7 May 2012 at 12:18:36 UTC, Steven Schveighoffer wrote:
 No, they are the same function.  size_t is aliased to uint.  What *you*  
 want size_t to mean is not what it is, it's an alias to the word-sized  
 unsigned integer on a platform.  Get used to it, use another type if  
 you don't want it to be that.

No kidding! I use a different language altogether when I don't like D. That doesn't tell me anything useful though...

Nothing in this whole thread seems to be very useful. I don't know how else to answer your post except -- sorry, we're not going to change it.
 It's the same in C/C++ BTW.  D's alias === C's typedef, and C's size_t  
 is a typedef.

Did you read my own response to someone else? You're telling me something I already mentioned myself... My response: "C++ doesn't even _have_ reflection, and it treats typedefs pretty much the same as D does right now..."

It's hard to see where you are coming from. You have mentioned that doing Windows low-level programming is hard on most platforms except for C. Well, if C made it easy, why not duplicate what they did?
 (2) I'm saying function(void*) and function(HANDLE) are different  
 functions, and people are telling me to use TypeDef. Which is of  
 course an alternative, except that it requires me to modify the source  
 code of my library.

Wait, you have to modify one type definition, right? Is that really not satisfactory? I don't understand this line of reasoning.

No, it's not satisfactory, because I'm not always in control of the type definition.

1) pull request. I'm sure a pull request that makes more correct semantic decisions on implicit casting of HANDLEs would be accepted. 2) Make your own types. You are free to not use standard/existing libraries. Given that you want to write an *entire toolkit*, I doubt anyone gives a shit whether your low-level code works with standard phobos-defined HANDLE types.
 I can't say I ever used typedef when it was allowed.

That doesn't make it useless. :P

This was not my reason for saying it. I was qualifying what I was about to say by saying "I don't have a lot of experience with typedefs".
 I can see how it can be useful in certain situations, but I think the  
 path is available to make an equivalent library solution work (it seems  
 several people have said it doesn't, why not spend time trying to fix  
 it rather than complaining about features that aren't coming back?)

Um... if people don't agree that size_t should be a different type, why would I spend time 'fixing' something that won't be used anyway?

I meant fixing the library solution so it *does* work how you want. In other words, "bringing back typedefs" isn't going to happen. It's not a solution that is practical, or likely. But making std.typecons.TypeDef work *is* a valid path to get what you want (typedefs that work like they used to). If that isn't possible, let's fix the language constructs that are blocking it!
 (I'm pretty sure none of the people who suggested using TypeDef for  
 HWND realized that we'd have to do the same thing for size_t and such.  
 Otherwise, when I'd have asked about that, the response wouldn't have  
 been "who cares".)

I think they didn't realize it because it's completely false ;) You saying it's not false doesn't make it any more true.

It might have been false, but if so, that falsehood definitely wasn't communicated. So from my perspective, it's true. (I don't have ESP to figure out what people *really* think of, sorry... and no pun intended :P)

No I mean it's completely false that fixing HWND means we have to fix size_t. size_t is not broken in any way, HWND is, and I agree we need a solution that works. -Steve
May 07 2012
prev sibling next sibling parent reply "Mehrdad" <wfunction hotmail.com> writes:
On Monday, 7 May 2012 at 17:17:55 UTC, Steven Schveighoffer wrote:
 Nothing in this whole thread seems to be very useful.  I don't 
 know how else to answer your post except -- sorry, we're not 
 going to change it.

Okay. Though you'd be a lot more convincing if you could give an example of how typedef was causing problems previously. I've asked that question several times, but no one's ever given me an actual *example* or two of the problems. If I saw one then obviously I'd understand why it was removed...
 It's hard to see where you are coming from.  You have mentioned 
 that doing Windows low-level programming is hard on most 
 platforms except for C.  Well, if C made it easy, why not 
 duplicate what they did?

I don't understand your response or where you got that idea, but I don't think my response would be very interesting even if I did...
 1) pull request.  I'm sure a pull request that makes more 
 correct semantic decisions on implicit casting of HANDLEs would 
 be accepted.

I'm busy right now but perhaps next week -- I'll try and see. (Haven't done one before so I may or may not succeed..)
 2) Make your own types.  You are free to not use 
 standard/existing libraries.

Yes, and I can write the rest of Phobos from scratch as well...
 Given that you want to write an *entire toolkit*, I doubt 
 anyone gives a shit whether your low-level code works with 
 standard phobos-defined HANDLE types.

I don't either, so you're definitely right about that. Especially because I really doubt my library's gonna turn out very useful anyway, even if all this was perfect.
 I meant fixing the library solution so it *does* work how you 
 want.  In other words, "bringing back typedefs" isn't going to 
 happen.  It's not a solution that is practical, or likely.

Yup, I'd love to know what the problems were though. (See the first part of the post.)
 But making std.typecons.TypeDef work *is* a valid path to get 
 what you want (typedefs that work like they used to).  If that 
 isn't possible, let's fix the language constructs that are 
 blocking it!

Okay, at least the road is clear now.
 No I mean it's completely false that fixing HWND means we have 
 to fix size_t.  size_t is not broken in any way, HWND is, and I 
 agree we need a solution that works.

Lol, ok, another case of miscommunication then.
May 07 2012
parent travert phare.normalesup.org (Christophe) writes:
"Mehrdad" , dans le message (digitalmars.D:166381), a crit:
 On Monday, 7 May 2012 at 20:25:35 UTC, Steven Schveighoffer wrote:
 On Mon, 07 May 2012 15:48:22 -0400, Mehrdad 
 <wfunction hotmail.com> wrote:

 I'm looking at this:

 m += 5; // ok
 m = m + 5; // error

 And thinking, hm.. this is no good :)

Yeah, that means they were implemented poorly. :P It should've been an error for both, because neither of them make sense. I don't see why the first one couldn't have been an error though, so I guess I'll have to dig up old threads on why the first one wasn't disallowed, since I can't see why we couldn't just disallow it right there...

One reason could be this : mint, just like int has an opOpAssign!"+" with takes an int, so "m += 5" is valid... Using any other rule raises a lot of questions: - Should all operators of typedef-type with its base-type parameter be rewritten to take a typedef-type ? - What about returned type? - What about methods that are not operators? - What about free functions? - If something is implicitely castable/promoted to the base type, should it be implicitely castable to the typedef ? What choice of typedef would you make? size_t is a good example of why typedef is poor. Should this compile, and if it does, what is the type of the result of the operations ? typedef uint size_t; size_t a, b; a - b; -b; a * b; a * 2; a * -2; a * 2u; I don't think typedef if a good solution to implement a type safe size_t. Solutions may be found in typesafe langages, but things are not as obvious as you would like them to be. -- Christophe
May 09 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 07 May 2012 14:08:33 -0400, Mehrdad <wfunction hotmail.com> wrote:

 On Monday, 7 May 2012 at 17:17:55 UTC, Steven Schveighoffer wrote:
 Nothing in this whole thread seems to be very useful.  I don't know how  
 else to answer your post except -- sorry, we're not going to change it.

Okay. Though you'd be a lot more convincing if you could give an example of how typedef was causing problems previously.

I think it was more that the whole concept was flawed -- typedef int myint never really did exactly what you wanted it to. For example: myint m = 1; // ok m += 5; // ok m = m + 5; // error? Things got even worse when you weren't typedef'ing a basic type. I think the advents in type construction in D2 have made typedef almost completely implementable as a library type, and we can do it the way it was intended! Don't forget, typedef was there when we had no "alias this" and no blanket operator overloading. When all you want is an opaque type that just can't be implicitly cast from something else (such as HANDLE) typedef is a crude and inaccurate method to do that.
 It's hard to see where you are coming from.  You have mentioned that  
 doing Windows low-level programming is hard on most platforms except  
 for C.  Well, if C made it easy, why not duplicate what they did?

I don't understand your response or where you got that idea, but I don't think my response would be very interesting even if I did...

Maybe it wasn't you, let me check... http://forum.dlang.org/post/jnueti$1opd$1 digitalmars.com OK, it was you, but under a different context, and I actually don't see you mentioning C there. Sorry for the confusion/accusation. I have a hard time keeping track of all these different threads in my head :(
 2) Make your own types.  You are free to not use standard/existing  
 libraries.

Yes, and I can write the rest of Phobos from scratch as well...

If it's better than phobos, then maybe we can use it! Seriously though, I get what you are saying. Fortunately, we have a very significant team working on phobos (I think more than a dozen people have commit rights), so the situation for "grr... phobos really should do *this*, but I can't get phobos changed" can be pretty readily resolved. Github and pull requests have made this incredibly easy. I've looked at some pull requests that were dead simple, verified it in a matter of minutes, and click one button to pull it. Even when I have no experience in the related modules. Brad Roberts (and I think Daniel Murphy?) have set up an awesome testing system that automatically verifies pull requests on all the supported platforms using the latest from git. See here: http://d.puremagic.com/test-results/pulls.ghtml The chances of your pull request being validated and pulled -- if it makes a good improvement to phobos -- are much much higher than they used to be. -Steve
May 07 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Monday, 7 May 2012 at 19:29:26 UTC, Steven Schveighoffer wrote:
 I think it was more that the whole concept was flawed -- 
 typedef int myint never really did exactly what you wanted it 
 to.

 For example:

 myint m = 1; // ok
 m += 5; // ok
 m = m + 5; // error?

It's definitely an error, because 5 isn't myint. Of course, it wouldn't be an error in C code, but keeping source compatibility isn't a goal either. Wouldn't a global search-and-replace that replaced "typedef" with "alias" when porting C code have fixed 99% of this issue, practically speaking?
 Things got even worse when you weren't typedef'ing a basic type.

It sounds so trivial to fix though (especially since it's not silent breakage)... Would you mind giving another (actual) example (perhaps with a custom type?) that came up, and which shows the extent of the problem and why it was difficult to solve without disallowing typedef entirely? I'm having a hard time seeing why the problem was so difficult (or tedious) to fix... a search/replace for typedef/alias would've fixed all (or almost) all the cases when porting C code, right?
 I think the advents in type construction in D2 have made 
 typedef almost completely implementable as a library type, and 
 we can do it the way it was intended!  Don't forget, typedef 
 was there when we had no "alias this" and no blanket operator 
 overloading.

Well, I'll have to try it and see -- I neither agree nor disagree. Right now I'm just trying to understand the problems it was causing, though.
 When all you want is an opaque type that just can't be 
 implicitly cast from something else (such as HANDLE) typedef is 
 a crude and inaccurate method to do that.

I don't really agree with that (though an example as I asked for above^ could definitely make me agree)
 Maybe it wasn't you, let me check...

 http://forum.dlang.org/post/jnueti$1opd$1 digitalmars.com

 OK, it was you, but under a different context, and I actually 
 don't see you mentioning C there.  Sorry for the 
 confusion/accusation.  I have a hard time keeping track of all 
 these different threads in my head :(

Haha no worries. :)
 Seriously though, I get what you are saying. [...] The chances 
 of your pull request being validated and pulled -- if it makes 
 a good improvement to phobos -- are much much higher than they 
 used to be.

Awesome, I'll probably try my hand at it (probably around next week). :)
May 07 2012
prev sibling next sibling parent "Francois Chabot" <francois.chabot.dev gmail.com> writes:
On Monday, 7 May 2012 at 19:29:26 UTC, Steven Schveighoffer wrote:
 Seriously though, I get what you are saying.  Fortunately, we 
 have a very significant team working on phobos (I think more 
 than a dozen people have commit rights), so the situation for 
 "grr... phobos really should do *this*, but I can't get phobos 
 changed" can be pretty readily resolved.  Github and pull 
 requests have made this incredibly easy.  I've looked at some 
 pull requests that were dead simple, verified it in a matter of 
 minutes, and click one button to pull it.  Even when I have no 
 experience in the related modules.  Brad Roberts (and I think 
 Daniel Murphy?) have set up an awesome testing system that 
 automatically verifies pull requests on all the supported 
 platforms using the latest from git.  See here:

 http://d.puremagic.com/test-results/pulls.ghtml

 The chances of your pull request being validated and pulled -- 
 if it makes a good improvement to phobos -- are much much 
 higher than they used to be.

 -Steve

Whoa! that auto-tester is pretty sharp! I've actually been wondering about this. I recently ran into a bug in Phobos, quickly tacked that there was an issue for it, made an easy fix, submitted a pull request and commented on the bug. All tests in the above page are coming out green, so I guess I've got that going for it. https://github.com/D-Programming-Language/phobos/pull/557 Is there some additional communication channel I need to notify for someone to have a look at it and at least comment on any errors/mistakes? Or am I pretty much stuck to wait for whoever is in charge of that module to run into it?
May 07 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 07 May 2012 15:48:22 -0400, Mehrdad <wfunction hotmail.com> wrote:

 On Monday, 7 May 2012 at 19:29:26 UTC, Steven Schveighoffer wrote:
 I think it was more that the whole concept was flawed -- typedef int  
 myint never really did exactly what you wanted it to.

 For example:

 myint m = 1; // ok
 m += 5; // ok
 m = m + 5; // error?

It's definitely an error, because 5 isn't myint. Of course, it wouldn't be an error in C code, but keeping source compatibility isn't a goal either.

I'm looking at this: m += 5; // ok m = m + 5; // error And thinking, hm.. this is no good :) C compatibility is not what we are after here, alias already handles C compatibility.
 Wouldn't a global search-and-replace that replaced "typedef" with  
 "alias" when porting C code have fixed 99% of this issue, practically  
 speaking?

No, it's not a portability issue. It's a WTF issue.
 Things got even worse when you weren't typedef'ing a basic type.

It sounds so trivial to fix though (especially since it's not silent breakage)... Would you mind giving another (actual) example (perhaps with a custom type?) that came up, and which shows the extent of the problem and why it was difficult to solve without disallowing typedef entirely? I'm having a hard time seeing why the problem was so difficult (or tedious) to fix... a search/replace for typedef/alias would've fixed all (or almost) all the cases when porting C code, right?

I'm almost 100% certain that the issues had nothing to do with C compatibility. It was all in how D typedefs behaved strangely. Not being one to have used them much, I can only recollect that one example. I do remember people bitching about them quite a bit, and nobody really having any good ideas on how to fix them, but I don't know circa what time period to look for those discussons. One person who was an ardent supporter of typedefs, and still wants *something* like them is bearophile. He might be able to list some issues/find some old posts/bugs that make more sense. -Steve
May 07 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Monday, 7 May 2012 at 20:25:35 UTC, Steven Schveighoffer wrote:
 On Mon, 07 May 2012 15:48:22 -0400, Mehrdad 
 <wfunction hotmail.com> wrote:

 I'm looking at this:

 m += 5; // ok
 m = m + 5; // error

 And thinking, hm.. this is no good :)

Yeah, that means they were implemented poorly. :P It should've been an error for both, because neither of them make sense. I don't see why the first one couldn't have been an error though, so I guess I'll have to dig up old threads on why the first one wasn't disallowed, since I can't see why we couldn't just disallow it right there...
 C compatibility is not what we are after here, alias already 
 handles C compatibility.

I see, ok.
 Not being one to have used them much, I can only recollect that 
 one example.  I do remember people bitching about them quite a 
 bit, and nobody really having any good ideas on how to fix 
 them, but I don't know circa what time period to look for those 
 discussons.  One person who was an ardent supporter of 
 typedefs, and still wants *something* like them is bearophile. 
 He might be able to list some issues/find some old posts/bugs 
 that make more sense.

Ah okay thanks. bearophile: If you see happen this, would you mind posting examples? :)
May 07 2012
prev sibling next sibling parent Gor Gyolchanyan <gor.f.gyolchanyan gmail.com> writes:
There's an _is_ expression, which allows one to determine the
underlying type of a enum:

template EnumType(T)
    if(is(T U = enum))
{
    alias U EnumType;
}

It would be awesome if the same mechanism was implemented for aliased types:

template AliasType(T)
    if(is(T U = alias))
{
    enum string AliasType = U;
}

which would return a string, containing the alias name.
May 08 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 But making std.typecons.TypeDef work *is* a valid path to get 
 what you want (typedefs that work like they used to).  If that 
 isn't possible, let's fix the language constructs that are 
 blocking it!

Right. Bye, bearophile
May 08 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, May 08, 2012 20:58:50 mta`chrono wrote:
 Am 08.05.2012 16:03, schrieb bearophile:
 Steven Schveighoffer:
 But making std.typecons.TypeDef work *is* a valid path to get what you
 want (typedefs that work like they used to). If that isn't possible,
 let's fix the language constructs that are blocking it!

Right. Bye, bearophile

Maybe it's not directly related to this topic, but shouldn't that be rather part of druntime?

Only if something else in druntime needs it, which it doesn't. - Jonathan M Davis
May 08 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, May 09, 2012 10:00:37 mta`chrono wrote:
 Maybe it's not directly related to this topic, but shouldn't that be
 rather part of druntime?

Only if something else in druntime needs it, which it doesn't. - Jonathan M Davis

There is a real trend to purify the language. I also think it's the right decision to replace compiler intrinsics / language feature with their library counterparts. Moving stuff to phobos is fine as long as you use phobos. But I'm using tango and druntime. I haven't even installed phobos on my system. The same impacts deimos. People tend to create unneccessary phobos dependencys.

In general, we're not sticking anything in druntime unless it needs to be there. It's also pretty much expected that projects will use Phobos. druntime isn't even provided at a separate library when distributed with dmd. If you're specifically trying to avoid using Phobos, you can do that, but don't expect stuff that doesn't need to be in druntime to be put into druntime just because you don't want to use D's standard library. Since Phobos is statically linked at this point, the parts that you don't use wouldn't be pulled in anyway. But you can also copy it from Phobos and put it in your project if you want to (as long as it doesn't have a lot of other dependencies in Phobos). Personally, I don't know how you could get by without using Phobos for at least std.traits unless you avoid templates (which would _really_ be reducing D's power - I'd hate to use D without templates), since it's a _lot_ harder to have good template constraints without std.traits. - Jonathan M Davis
May 09 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
Okay, I just tried changing "alias void*" to "alias 
Typedef(void*)", and also "alias HANDLE" to "alias 
Typedef(HANDLE)", etc.

First error I got?

	HMODULE hAdvapi32 = null;
	...\src\phobos\std\internal\windows\advapi32.d(32):
	Error:
	cannot implicitly convert expression (null) of type typeof(null) 
to Typedef!(Typedef!(void*,null),Typedef(null))


Which makes sense, except that I'm not sure how to solve it 
correctly in general...
I think it's a bigger problem than it looks, since 'null' would 
need to be convertible to everything that's nullable...

ideas?
May 11 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 11 May 2012 14:56:45 -0400, Mehrdad <wfunction hotmail.com> wrote:

 Okay, I just tried changing "alias void*" to "alias Typedef(void*)", and  
 also "alias HANDLE" to "alias Typedef(HANDLE)", etc.

 First error I got?

 	HMODULE hAdvapi32 = null;
 	...\src\phobos\std\internal\windows\advapi32.d(32):
 	Error:
 	cannot implicitly convert expression (null) of type typeof(null) to  
 Typedef!(Typedef!(void*,null),Typedef(null))


 Which makes sense, except that I'm not sure how to solve it correctly in  
 general...
 I think it's a bigger problem than it looks, since 'null' would need to  
 be convertible to everything that's nullable...

This is a frequent problem with null. Since null is its own type now, it doesn't play nice with custom types, only builtins enjoy special treatment for null.
 ideas?

probably something like opBool: struct S { int x; static S opNull() { return S(0);} } S s = null; // equivalent to S(0); -Steve
May 11 2012
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
On Friday, 11 May 2012 at 19:04:52 UTC, Steven Schveighoffer 
wrote:
 This is a frequent problem with null.  Since null is its own 
 type now, it doesn't play nice with custom types, only builtins 
 enjoy special treatment for null.

It is????? O_________O (welcome to Python, lol...)
 probably something like opBool:

 struct S
 {
   int x;
   static S opNull() { return S(0);}
 }

 S s = null; // equivalent to S(0);

Ohhmmmmmmmmmmmm interesting, lemme look at that... thanks
May 11 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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?
May 11 2012
prev sibling next sibling parent "Chris Cain" <clcain uncg.edu> writes:
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
prev sibling next sibling parent "David Nadlinger" <see klickverbot.at> writes:
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
prev sibling next sibling parent "Robert DaSilva" <spunit262 yahoo.com> writes:
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
prev sibling next sibling parent "Chris Cain" <clcain uncg.edu> writes:
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
prev sibling next sibling parent "Mehrdad" <wfunction hotmail.com> writes:
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
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
May 17 2012
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, May 17, 2012 at 04:29:57PM +0200, bearophile wrote:
 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

Heh, I've actually voted for that bug before, and forgot about it afterwards. :-) T -- It said to install Windows 2000 or better, so I installed Linux instead.
May 17 2012