May 06, 2012
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 06, 2012
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
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
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
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
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
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
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 07, 2012
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
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