Thread overview
bug in typeof or wrong enum specs?
Aug 28, 2013
captaindet
Aug 28, 2013
Dicebot
Aug 29, 2013
Jacob Carlborg
Aug 29, 2013
Rainer Schuetze
Aug 29, 2013
captaindet
Aug 29, 2013
Maxim Fomin
Aug 30, 2013
captaindet
Aug 29, 2013
Jacob Carlborg
Aug 29, 2013
captaindet
August 28, 2013
a recent discussion ( http://forum.dlang.org/thread/kvje4r$1tff$1@digitalmars.com ) about the official enum dox ( http://dlang.org/enum.html ) was not conclusive whether

	enum IDENTIFIER;

is officially allowed/supported. jacob pointed out that it has an important use case in that it can serve as UDA. as UDAs are fairly new, this cannot be the reason why this syntax was allowed in the first place though, *if* it is allowed. also, it might be used in meta stuff similar to "#define IDENTIFIER" in C - playing with this idea i run into this issue...

while much code behaves with such an empty enum declaration,

	writeln( __traits(compiles, IDENTIFIER) );	// true
	writeln( is( IDENTIFIER == enum ) );			// true

typeof() is not happy at all (DMD 2.063.2):

	writeln( typeof(IDENTIFIER).stringof );		
	// Error: argument IDENTIFIER to typeof is not an expression

typeof() expects an expression and a bare identifier is a "PrimaryExpression" ( http://dlang.org/expression.html#PrimaryExpression ) and hence a valid argument.

either the empty enum declaration is not allowed (and should be removed from the dox and throw a compilation error) or there is a bug in typeof().


/det
August 28, 2013
On Wednesday, 28 August 2013 at 23:28:14 UTC, captaindet wrote:
> a recent discussion ( http://forum.dlang.org/thread/kvje4r$1tff$1@digitalmars.com ) about the official enum dox ( http://dlang.org/enum.html ) was not conclusive whether
>
> 	enum IDENTIFIER;
>
> is officially allowed/supported. jacob pointed out that it has an important use case in that it can serve as UDA. as UDAs are fairly new, this cannot be the reason why this syntax was allowed in the first place though, *if* it is allowed. also, it might be used in meta stuff similar to "#define IDENTIFIER" in C - playing with this idea i run into this issue...
>
> while much code behaves with such an empty enum declaration,
>
> 	writeln( __traits(compiles, IDENTIFIER) );	// true
> 	writeln( is( IDENTIFIER == enum ) );			// true
>
> typeof() is not happy at all (DMD 2.063.2):
>
> 	writeln( typeof(IDENTIFIER).stringof );		
> 	// Error: argument IDENTIFIER to typeof is not an expression
>
> typeof() expects an expression and a bare identifier is a "PrimaryExpression" ( http://dlang.org/expression.html#PrimaryExpression ) and hence a valid argument.
>
> either the empty enum declaration is not allowed (and should be removed from the dox and throw a compilation error) or there is a bug in typeof().
>
>
> /det

typeof only accepts expressions, not types. enum symbol acts as a type here as it does not have associated value (typeof(int) will result in same error message)
August 29, 2013
On 2013-08-29 01:28, captaindet wrote:
> a recent discussion (
> http://forum.dlang.org/thread/kvje4r$1tff$1@digitalmars.com ) about the
> official enum dox ( http://dlang.org/enum.html ) was not conclusive whether
>
>      enum IDENTIFIER;
>
> is officially allowed/supported. jacob pointed out that it has an
> important use case in that it can serve as UDA. as UDAs are fairly new,
> this cannot be the reason why this syntax was allowed in the first place
> though, *if* it is allowed.

No, but now it's a useful use case.

> also, it might be used in meta stuff similar
> to "#define IDENTIFIER" in C - playing with this idea i run into this
> issue...
>
> while much code behaves with such an empty enum declaration,
>
>      writeln( __traits(compiles, IDENTIFIER) );    // true
>      writeln( is( IDENTIFIER == enum ) );            // true
>
> typeof() is not happy at all (DMD 2.063.2):
>
>      writeln( typeof(IDENTIFIER).stringof );
>      // Error: argument IDENTIFIER to typeof is not an expression
>
> typeof() expects an expression and a bare identifier is a
> "PrimaryExpression" ( http://dlang.org/expression.html#PrimaryExpression
> ) and hence a valid argument.
>
> either the empty enum declaration is not allowed (and should be removed
> from the dox and throw a compilation error) or there is a bug in typeof().

No, I previously misread your post.

enum foo;

The above declares a type, with the name "foo".

enum bar = 1;

Declares a manifest constant, short for:

enum int bar = 1;

The type is "int", the name of the constant is "bar".

typeof(bar); // ok, "bar" is not a type
typeof(int); // error, "int" is a type
typeof(foo); // error, "foo" is a type

Although I do think that typeof(type) should work and just return "type".

-- 
/Jacob Carlborg
August 29, 2013

On 29.08.2013 01:28, captaindet wrote:
> a recent discussion (
> http://forum.dlang.org/thread/kvje4r$1tff$1@digitalmars.com ) about the
> official enum dox ( http://dlang.org/enum.html ) was not conclusive whether
>
>      enum IDENTIFIER;
>
> is officially allowed/supported. jacob pointed out that it has an
> important use case in that it can serve as UDA. as UDAs are fairly new,
> this cannot be the reason why this syntax was allowed in the first place
> though, *if* it is allowed. also, it might be used in meta stuff similar
> to "#define IDENTIFIER" in C - playing with this idea i run into this
> issue...

enum IDENTIFIER;

was used to help resolving forward references to type IDENTIFIER when the resolving of forward references was a lot less capable than it is now. I don't think it is still needed for that. The same syntax exists for struct or class.

Please also note that using it as in C/C++ to declare a type that is actually defined in another module does not work. The type is bound to the current module and the definition has to be in that module.
August 29, 2013
thanks dicebot, jacob, rainer.

now i understand better what is going on and why.

however, i don't see the issue fully resolved. in

enum IDENTIFIER;

IDENTIFIER is an identifier, there is no way around it. the enum declaration makes it a type too, but it continues to be an identifier. an identifier is a "PrimaryExpression". a "PrimaryExpression" is an "Expression", any expression is officially allowed in typeof. but it throws an error because this expression is a type too.

same goes with

alias IDENTIFIER2 = int;

i don't think it can/should be fixed for identifiers only but instead typeof() should cover types in general:

typeof(IDENTIFIER) = IDENTIFIER
typeof(IDENTIFIER2 ) = int
typeof(int) = int

i see only advantages in this and it would clean up meta code from handling corner cases. (at least in my case, but being still on the newbie side of D programming i might not do it right.)

/det
August 29, 2013
On Thursday, 29 August 2013 at 16:15:50 UTC, captaindet wrote:
>
> however, i don't see the issue fully resolved. in
>
> enum IDENTIFIER;
>
> IDENTIFIER is an identifier, there is no way around it. the enum declaration makes it a type too, but it continues to be an identifier. an identifier is a "PrimaryExpression". a "PrimaryExpression" is an "Expression", any expression is officially allowed in typeof. but it throws an error because this expression is a type too.
>
> same goes with
>
> alias IDENTIFIER2 = int;


Grammar rule "expression" is not necessarily an expression in a general sense  of computing values, designating objects or producing side effects.

> i don't think it can/should be fixed for identifiers only but instead typeof() should cover types in general:
>
> typeof(IDENTIFIER) = IDENTIFIER
> typeof(IDENTIFIER2 ) = int
> typeof(int) = int
>
> i see only advantages in this and it would clean up meta code from handling corner cases. (at least in my case, but being still on the newbie side of D programming i might not do it right.)
>
> /det

Yes.
August 29, 2013
On 2013-08-29 18:15, captaindet wrote:

> i see only advantages in this and it would clean up meta code from
> handling corner cases. (at least in my case, but being still on the
> newbie side of D programming i might not do it right.)

I've already created an enhancement request:

http://d.puremagic.com/issues/show_bug.cgi?id=10919

-- 
/Jacob Carlborg
August 29, 2013
On 2013-08-29 14:24, Jacob Carlborg wrote:
> On 2013-08-29 18:15, captaindet wrote:
>
>> i see only advantages in this and it would clean up meta code from
>> handling corner cases. (at least in my case, but being still on the
>> newbie side of D programming i might not do it right.)
>
> I've already created an enhancement request:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=10919

thanks! i have just voted for it ;)

August 30, 2013
On 2013-08-29 12:17, Maxim Fomin wrote:
> On Thursday, 29 August 2013 at 16:15:50 UTC, captaindet wrote:
>>
>> however, i don't see the issue fully resolved. in
>>
>> enum IDENTIFIER;
>>
>> IDENTIFIER is an identifier, there is no way around it. the enum
>> declaration makes it a type too, but it continues to be an
>> identifier. an identifier is a "PrimaryExpression". a
>> "PrimaryExpression" is an "Expression", any expression is
>> officially allowed in typeof. but it throws an error because this
>> expression is a type too.
>>
>> same goes with
>>
>> alias IDENTIFIER2 = int;
>
>
> Grammar rule "expression" is not necessarily an expression in a
> general sense of computing values, designating objects or producing
> side effects.

cannot say that this makes it clearer to me. if there is something fuzzy/wrong in the dox or grammar rules then it needs to be fixed. to me, according to the current language specs, an expression can already be (Identifier) or evaluate to a type and typeof(expression) should not throw but return this type. so far i have not seen any convincing explanation why a different behavior is desirable or is making any sense.

/det