Thread overview
question...
Jan 09, 2008
Aarti_pl
Jan 09, 2008
Daniel919
Jan 09, 2008
Aarti_pl
Jan 09, 2008
Aziz K.
Jan 09, 2008
Marcin Kuszczak
Jan 09, 2008
Aziz K.
Jan 10, 2008
Bill Baxter
Jan 10, 2008
Aarti_pl
Jan 10, 2008
Aarti_pl
Jan 10, 2008
Robert DaSilva
January 09, 2008
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
> 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
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
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
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
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
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
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
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
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