Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 09, 2008 question... | ||||
---|---|---|---|---|
| ||||
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) |
January 09, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aarti_pl | > 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** ));
|
January 09, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel919 | 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
|
January 09, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aarti_pl | 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 this 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) == 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 |
January 09, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aziz K. | 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/ ------------------------------------- |
January 09, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marcin Kuszczak | 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
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
|
January 10, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aziz K. | 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
|
January 10, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aziz K. | 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)
|
January 10, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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)
|
January 10, 2008 Re: question... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aarti_pl | 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 |
Copyright © 1999-2021 by the D Language Foundation