www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - bug in typeof or wrong enum specs?

reply captaindet <2krnk gmx.net> writes:
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
Aug 28 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
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)
Aug 28 2013
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
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
Aug 28 2013
prev sibling next sibling parent Rainer Schuetze <r.sagitario gmx.de> writes:
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.
Aug 28 2013
prev sibling parent reply captaindet <2krnk gmx.net> writes:
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
Aug 29 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
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.
Aug 29 2013
parent captaindet <2krnk gmx.net> writes:
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
Aug 30 2013
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
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
Aug 29 2013
parent captaindet <2krnk gmx.net> writes:
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 ;)
Aug 29 2013