www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - question...

reply Aarti_pl <aarti interia.pl> writes:
Few minutes ago I recall my previous post here. The problem was that I 
tried to use:

new (int*);

Compiler rejected this style of creating type. But I found out that this 
works properly:

new int*;

I think that it would be nice to have first style of creating types also 
(it was discussed, but no answer from Walter AFAIK).

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

Above is ok. for me currently, but I have different problem:

void main() {
     class A {}
     static assert(is( typeof(new A) == typeof(A)) ); // 1
     static assert(is( typeof(new int*) == typeof(int*) )); // 2
}

First assert compiles, but the second one not.

Any comments on this?

BR
Marcin Kuszczak
(aarti_pl)
Jan 09 2008
next sibling parent reply Daniel919 <Daniel919 web.de> writes:
 void main() {
     class A {}
     static assert(is( typeof(new A) == typeof(A)) ); // 1
     static assert(is( typeof(new int*) == typeof(int*) )); // 2
 }
 
 First assert compiles, but the second one not.

It's because of the difference that - classes are reference types - basic data types and structs are value types These are working: //reference type class A {} static assert(is( typeof(new A) == A )); //value type struct B {} static assert(is( typeof(new B) == B* )); static assert(is( typeof(new int) == int* )); static assert(is( typeof(new int*) == int** ));
Jan 09 2008
parent Aarti_pl <aarti interia.pl> writes:
Daniel919 pisze:
 void main() {
     class A {}
     static assert(is( typeof(new A) == typeof(A)) ); // 1
     static assert(is( typeof(new int*) == typeof(int*) )); // 2
 }

 First assert compiles, but the second one not.

It's because of the difference that - classes are reference types - basic data types and structs are value types These are working: //reference type class A {} static assert(is( typeof(new A) == A )); //value type struct B {} static assert(is( typeof(new B) == B* )); static assert(is( typeof(new int) == int* )); static assert(is( typeof(new int*) == int** ));

Yes, sure. I missed one asterisk in second assert. But I think that it is compiler bug that second assert in my example (with typeof(int**)) doesn't compile at all. At least on my computer with DMD 1.025, while it is IMHO perfectly correct. What's more error message is completely misleading: quicktest.d(62): found '*' when expecting '.' following 'int' quicktest.d(62): found ')' when expecting identifier following 'int.' quicktest.d(62): found ';' when expecting ')' quicktest.d(64): found '}' when expecting ';' quicktest.d(65): found 'EOF' instead of statement quicktest.d(65): found 'EOF' instead of statement quicktest.d(65): found 'EOF' instead of statement I will probably report it as a bug. While it has not so much sense to do: typeof(int**) it should nevertheless work as expected or at least report proper error. BR Marcin Kuszczak
Jan 09 2008
prev sibling parent reply "Aziz K." <aziz.kerim gmail.com> writes:
Hi,
Aarti_pl wrote:
 Few minutes ago I recall my previous post here. The problem was that I=

 tried to use:

 new (int*);

 Compiler rejected this style of creating type. But I found out that th=

 works properly:

It doesn't work because it's a syntax error according to the D grammar. After "new" a "Type" is expected which never starts with an opening = parenthesis.
 ----------------------------------

 Above is ok. for me currently, but I have different problem:

 void main() {
      class A {}
      static assert(is( typeof(new A) =3D=3D typeof(A)) ); // 1
      static assert(is( typeof(new int*) =3D=3D typeof(int*) )); // 2
 }

 First assert compiles, but the second one not.

The second one doesn't compile because it isn't syntactically correct. The error lies in "typeof(int*)". You are feeding the typeof expression = = with a "Type" ("int*"), but it expects an "Expression" (like "int.max", = = "new A", "2+5i" etc.) The purpose of typeof is to evaluate (without = side-effects) the expression contained in it and return the type of that= . Regards, Aziz
Jan 09 2008
next sibling parent reply Marcin Kuszczak <aarti_please_no spam_interia.pl> writes:
Aziz K. wrote:

 Above is ok. for me currently, but I have different problem:

 void main() {
 class A {}
 static assert(is( typeof(new A) == typeof(A)) ); // 1
 static assert(is( typeof(new int*) == typeof(int*) )); // 2
 }

 First assert compiles, but the second one not.

The second one doesn't compile because it isn't syntactically correct. The error lies in "typeof(int*)". You are feeding the typeof expression with a "Type" ("int*"), but it expects an "Expression" (like "int.max", "new A", "2+5i" etc.) The purpose of typeof is to evaluate (without side-effects) the expression contained in it and return the type of that. Regards, Aziz

Thanks but explanation. But I think that somethink is wrong here anyway. Please see first example. 'A' is also not expression, but it compiles properly. Maybe it would not be a big problem to extend typeof in such a way that it can accept types also. -- Regards Marcin Kuszczak (Aarti_pl) ------------------------------------- Ask me why I believe in Jesus - http://www.zapytajmnie.com (en/pl) Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/ -------------------------------------
Jan 09 2008
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Aziz K. wrote:
 Marcin Kuszczak wrote:
 Thanks but explanation. But I think that somethink is wrong here anyway.
 Please see first example. 'A' is also not expression, but it compiles
 properly. Maybe it would not be a big problem to extend typeof in such a
 way that it can accept types also.

This is the example: class A {} static assert(is( typeof(new A) == typeof(A)) ); // 1 [...] You suggested to extend typeof to allow Types as well. I don't think that's a good idea and I think it's not going to happen (ie. Walter won't implement it.) The reason is that typeof has one perfect purpose, that is to get the type of an expression. I don't see any sense in passing a Type to typeof in order to get what you had in the beginning anyway. Maybe there could be a legitimate use-case for this, but I'd like to see convincing examples where this would be meaningful and useful.

Yes, if anything typeof(A) should logically be "Type". I.e. the type of types. (which is what you get in Python and probably other languages with first-class types) --bb
Jan 09 2008
parent Aarti_pl <aarti interia.pl> writes:
Bill Baxter pisze:
 Aziz K. wrote:
 Marcin Kuszczak wrote:
 Thanks but explanation. But I think that somethink is wrong here anyway.
 Please see first example. 'A' is also not expression, but it compiles
 properly. Maybe it would not be a big problem to extend typeof in such a
 way that it can accept types also.

This is the example: class A {} static assert(is( typeof(new A) == typeof(A)) ); // 1 [...] You suggested to extend typeof to allow Types as well. I don't think that's a good idea and I think it's not going to happen (ie. Walter won't implement it.) The reason is that typeof has one perfect purpose, that is to get the type of an expression. I don't see any sense in passing a Type to typeof in order to get what you had in the beginning anyway. Maybe there could be a legitimate use-case for this, but I'd like to see convincing examples where this would be meaningful and useful.

Yes, if anything typeof(A) should logically be "Type". I.e. the type of types. (which is what you get in Python and probably other languages with first-class types) --bb

I don't understand your argument. My proposition doesn't change this behavior at all. typeof(<type>) is just special a special case for typeof(<many types>). BR Marcin Kuszczak (aarti_pl)
Jan 10 2008
prev sibling parent reply Aarti_pl <aarti interia.pl> writes:
Aziz K. pisze:
 Marcin Kuszczak wrote:
 Thanks for explanation. But I think that something is wrong here anyway.
 Please see first example. 'A' is also not expression, but it compiles
 properly. Maybe it would not be a big problem to extend typeof in such a
 way that it can accept types also.

This is the example: class A {} static assert(is( typeof(new A) == typeof(A)) ); // 1 The 'A' in typeof is an expression. Of course a human reader can see that it actually is a type (class A), but to a D parser it is an "Expression" because that's what the grammar rules say. Only when the semantic pass is started, identifiers can be resolved to the symbol they refer to, which could be a variable, a function, a class, a type etc. That means, what an identifier in an Expression actually is can only be determined in the semantic phase. But on the other hand, identifiers in "Types" must always refer to type symbols (if they don't, it's a semantic error.) In short, depending on the syntax tree produced in the parsing phase: * in a Type tree, identifiers must refer to classes, structs, aliases, typedefs etc. * in an Expression tree, identifiers can be anything. You suggested to extend typeof to allow Types as well. I don't think that's a good idea and I think it's not going to happen (ie. Walter won't implement it.) The reason is that typeof has one perfect purpose, that is to get the type of an expression. I don't see any sense in passing a Type to typeof in order to get what you had in the beginning anyway. Maybe there could be a legitimate use-case for this, but I'd like to see convincing examples where this would be meaningful and useful. Regards, Aziz

Well, even greater explanation :-) Thanks! Now I understand why it works like that. Nevertheless I still think that I should look at DMD front end from user point of view. I will probably never understand compiler arcana as good as e.g. Walter, so it's probably not my job to think about it from this perspective. And from user point of view I would still argue that it is kind of bug. Something what is very similar from user point of view behaves completely different: 'A' is a type, and int is a type, so it should behave similarly. You asked for use case. There is one (very simple, well, even simplistic :-) ) 1. Duplicate line with expression typeof(A) 2. Change A to int 3. Get surprised by unexpected and error -------------- I see following possibilities: 1. Improve error message, which is completely unhelpful 2. Allow simple types in typeof() Please notice that when Walter choose first option, he has a really tough job to explain in short error message why there can be type 'A', but there can not be int. I completely agree that this bug/enhancement has low priority. But I hope you see some merits in what I have written. I will put it as enhancement request on bugzilla. With low priority... :-) BR Marcin Kuszczak (aarti_pl)
Jan 10 2008
parent Robert DaSilva <sp.unit.262+digitalmars gmail.com> writes:
Aarti_pl wrote:
 Aziz K. pisze:
 Marcin Kuszczak wrote:
 Thanks for explanation. But I think that something is wrong here anyway.
 Please see first example. 'A' is also not expression, but it compiles
 properly. Maybe it would not be a big problem to extend typeof in such a
 way that it can accept types also.

This is the example: class A {} static assert(is( typeof(new A) == typeof(A)) ); // 1 The 'A' in typeof is an expression. Of course a human reader can see that it actually is a type (class A), but to a D parser it is an "Expression" because that's what the grammar rules say. Only when the semantic pass is started, identifiers can be resolved to the symbol they refer to, which could be a variable, a function, a class, a type etc. That means, what an identifier in an Expression actually is can only be determined in the semantic phase. But on the other hand, identifiers in "Types" must always refer to type symbols (if they don't, it's a semantic error.) In short, depending on the syntax tree produced in the parsing phase: * in a Type tree, identifiers must refer to classes, structs, aliases, typedefs etc. * in an Expression tree, identifiers can be anything. You suggested to extend typeof to allow Types as well. I don't think that's a good idea and I think it's not going to happen (ie. Walter won't implement it.) The reason is that typeof has one perfect purpose, that is to get the type of an expression. I don't see any sense in passing a Type to typeof in order to get what you had in the beginning anyway. Maybe there could be a legitimate use-case for this, but I'd like to see convincing examples where this would be meaningful and useful. Regards, Aziz

Well, even greater explanation :-) Thanks! Now I understand why it works like that. Nevertheless I still think that I should look at DMD front end from user point of view. I will probably never understand compiler arcana as good as e.g. Walter, so it's probably not my job to think about it from this perspective. And from user point of view I would still argue that it is kind of bug. Something what is very similar from user point of view behaves completely different: 'A' is a type, and int is a type, so it should behave similarly. You asked for use case. There is one (very simple, well, even simplistic :-) ) 1. Duplicate line with expression typeof(A) 2. Change A to int 3. Get surprised by unexpected and error -------------- I see following possibilities: 1. Improve error message, which is completely unhelpful 2. Allow simple types in typeof() Please notice that when Walter choose first option, he has a really tough job to explain in short error message why there can be type 'A', but there can not be int. I completely agree that this bug/enhancement has low priority. But I hope you see some merits in what I have written. I will put it as enhancement request on bugzilla. With low priority... :-) BR Marcin Kuszczak (aarti_pl)

There already is. http://d.puremagic.com/issues/show_bug.cgi?id=1341
Jan 10 2008
prev sibling parent "Aziz K." <aziz.kerim gmail.com> writes:
Marcin Kuszczak wrote:
 Thanks but explanation. But I think that somethink is wrong here anywa=

 Please see first example. 'A' is also not expression, but it compiles
 properly. Maybe it would not be a big problem to extend typeof in such=

 way that it can accept types also.

This is the example: class A {} static assert(is( typeof(new A) =3D=3D typeof(A)) ); // 1 The 'A' in typeof is an expression. Of course a human reader can see tha= t = it actually is a type (class A), but to a D parser it is an "Expression"= = because that's what the grammar rules say. Only when the semantic pass i= s = started, identifiers can be resolved to the symbol they refer to, which = = could be a variable, a function, a class, a type etc. That means, what an identifier in an Expression actually is can only be = = determined in the semantic phase. But on the other hand, identifiers in = = "Types" must always refer to type symbols (if they don't, it's a semanti= c = error.) In short, depending on the syntax tree produced in the parsing phase: * in a Type tree, identifiers must refer to classes, structs, aliases= , = typedefs etc. * in an Expression tree, identifiers can be anything. You suggested to extend typeof to allow Types as well. I don't think = that's a good idea and I think it's not going to happen (ie. Walter won'= t = implement it.) The reason is that typeof has one perfect purpose, that i= s = to get the type of an expression. I don't see any sense in passing a Typ= e = to typeof in order to get what you had in the beginning anyway. Maybe = there could be a legitimate use-case for this, but I'd like to see = convincing examples where this would be meaningful and useful. Regards, Aziz
Jan 09 2008