www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Convert Identifier to String at compile-time?

reply Garett Bass <garettbass studiotekne.com> writes:
Is there any template means by which I can create a string representation from
an identifier name at compile time?  I.e. given the identifier name i, I'd like
a template that can create a string "i".  Thanks in advance for any ideas.

Regards,
Garett
Jan 13 2006
next sibling parent reply John Reimer <terminal.node gmail.com> writes:
Garett Bass wrote:
 Is there any template means by which I can create a string 
 representation from an identifier name at compile time?  I.e. given the 
 identifier name i, I'd like a template that can create a string "i".  
 Thanks in advance for any ideas.
 
 Regards,
 Garett
I asked for this sort of feature in another post last year. The compiler currently does not have this ability, although I think it's important and useful. If the D infrastructure is to be capable of replacing the preprocessors of languages like C/C++, it will need to offer some capability of this sort. While exceedingly elegant compared to preprocessor macros, version control and templates just don't provide comprehensive functionality yet (in this particular area, anyway; templates in D are a wonderful simplification of C++ templates obfuscation). -JJR
Jan 13 2006
parent reply Don Clugston <dac nospam.com.au> writes:
John Reimer wrote:
 Garett Bass wrote:
 
 Is there any template means by which I can create a string 
 representation from an identifier name at compile time?  I.e. given 
 the identifier name i, I'd like a template that can create a string 
 "i".  Thanks in advance for any ideas.

 Regards,
 Garett
I asked for this sort of feature in another post last year. The compiler currently does not have this ability, although I think it's important and useful. If the D infrastructure is to be capable of replacing the preprocessors of languages like C/C++, it will need to offer some capability of this sort. While exceedingly elegant compared to preprocessor macros, version control and templates just don't provide comprehensive functionality yet (in this particular area, anyway; templates in D are a wonderful simplification of C++ templates obfuscation). -JJR
I've been able to hack an implementation together. The qualifiednameof!(X) metafunction gives the mangled fully qualified name of the symbol X, which includes the complete name and some type information. Works for any symbol which is permitted as a template alias parameter (ie, won't work for module names, member variables, or local variables. But it does work for any type, template, function, global or static variable). It relies on the current name-mangling algorithm, but at least that is now documented. http://svn.dsource.org/projects/ddl/trunk/meta/qualifiedname.d My test program is here, which demangles the name to give something more human-readable. Please forgive the poor state of this code; it's not ready to be used elsewhere. But it demonstrates what's currently possible for compile-time reflection. It might give you some ideas... http://svn.dsource.org/projects/ddl/trunk/meta/qualtest.d With the declarations... --------------------------------- class HeresAClass { void MemberFunc() { } struct AndAnInnerStruct {} } extern int someExternalInt; real aStaticFunction() { return 2.5;} HeresAClass anInstance; template ThisIsATemplate (A) { int something; } extern (Windows) real aWindowsFunction(int a, real b) { return b; } extern (C) real aCFunction(int a, real b) { return b; } typedef HeresAClass TypedefClass; enum HeresAnEnum { Val1, Val2, Val3 }; --------------------------------- Then with statements like... pragma(msg, describe!(HeresAClass)); pragma(msg, describe!(HeresAClass.AndAnInnerStruct)); pragma(msg, describe!(TypedefClass)); : pragma(msg, describe!(ThisIsATemplate!(int))); the program output is (at compile time, no exe is generated): dmd -c meta/qualtest.d === Compile time reflection === Class: qualtest.HeresAClass Struct: qualtest.HeresAClass.AndAnInnerStruct Typedef: qualtest.TypedefClass Enum: qualtest.HeresAnEnum * With D linkage, the type is at the end of the name D external: qualtest.aStaticFunction (and type is: FZe) D external: qualtest.HeresAClass.MemberFunc (and type is: FZv) D external: qualtest.anInstance (and type is: C8qualtest11HeresAClass) D external: qualtest.someExternalInt (and type is: i) * Special cases Special: aCFunction Special: aWindowsFunction Special: (Template) qualtest.ThisIsATemplate Special: (Template) qualtest.__T15ThisIsATemplateTiZ
Jan 18 2006
next sibling parent John Reimer <terminal.node gmail.com> writes:
Don Clugston wrote:

 I've been able to hack an implementation together. The 
 qualifiednameof!(X) metafunction gives
 the mangled fully qualified name of the symbol X, which includes the 
 complete name and some type information.
... Very impressive, Don! I didn't know that was possible. Thank you. I will check it out (literally :) ). -JJR
Jan 18 2006
prev sibling parent reply John Reimer <terminal.node gmail.com> writes:
Don Clugston wrote:
 John Reimer wrote:
 Garett Bass wrote:

 Is there any template means by which I can create a string 
 representation from an identifier name at compile time?  I.e. given 
 the identifier name i, I'd like a template that can create a string 
 "i".  Thanks in advance for any ideas.

 Regards,
 Garett
I asked for this sort of feature in another post last year. The compiler currently does not have this ability, although I think it's important and useful. If the D infrastructure is to be capable of replacing the preprocessors of languages like C/C++, it will need to offer some capability of this sort. While exceedingly elegant compared to preprocessor macros, version control and templates just don't provide comprehensive functionality yet (in this particular area, anyway; templates in D are a wonderful simplification of C++ templates obfuscation). -JJR
I've been able to hack an implementation together. The qualifiednameof!(X) metafunction gives the mangled fully qualified name of the symbol X, which includes the complete name and some type information. Works for any symbol which is permitted as a template alias parameter (ie, won't work for module names, member variables, or local variables. But it does work for any type, template, function, global or static variable). It relies on the current name-mangling algorithm, but at least that is now documented. http://svn.dsource.org/projects/ddl/trunk/meta/qualifiedname.d My test program is here, which demangles the name to give something more human-readable. Please forgive the poor state of this code; it's not ready to be used elsewhere. But it demonstrates what's currently possible for compile-time reflection. It might give you some ideas... http://svn.dsource.org/projects/ddl/trunk/meta/qualtest.d With the declarations... --------------------------------- class HeresAClass { void MemberFunc() { } struct AndAnInnerStruct {} } extern int someExternalInt; real aStaticFunction() { return 2.5;} HeresAClass anInstance; template ThisIsATemplate (A) { int something; } extern (Windows) real aWindowsFunction(int a, real b) { return b; } extern (C) real aCFunction(int a, real b) { return b; } typedef HeresAClass TypedefClass; enum HeresAnEnum { Val1, Val2, Val3 }; --------------------------------- Then with statements like... pragma(msg, describe!(HeresAClass)); pragma(msg, describe!(HeresAClass.AndAnInnerStruct)); pragma(msg, describe!(TypedefClass)); : pragma(msg, describe!(ThisIsATemplate!(int))); the program output is (at compile time, no exe is generated): dmd -c meta/qualtest.d === Compile time reflection === Class: qualtest.HeresAClass Struct: qualtest.HeresAClass.AndAnInnerStruct Typedef: qualtest.TypedefClass Enum: qualtest.HeresAnEnum * With D linkage, the type is at the end of the name D external: qualtest.aStaticFunction (and type is: FZe) D external: qualtest.HeresAClass.MemberFunc (and type is: FZv) D external: qualtest.anInstance (and type is: C8qualtest11HeresAClass) D external: qualtest.someExternalInt (and type is: i) * Special cases Special: aCFunction Special: aWindowsFunction Special: (Template) qualtest.ThisIsATemplate Special: (Template) qualtest.__T15ThisIsATemplateTiZ
Don, While I am very impressed at how you managed to do this, I am somewhat disturbed to see the gymnastics it took to get there. It shouldn't be that hard to do. If the D compiler had a simple command, property or whatever in place to accomplish the same task, we wouldn't have to go to such trouble. I was going to use the code in a project... but I'm a little hesitant to do so at the moment. I just about went cross-eyed trying to figure out how you managed that! lol! (in fact, I never did figure it out). I think D history will forever remember you as the "template ninja." -JJR
Jan 19 2006
parent reply Don Clugston <dac nospam.com.au> writes:
John Reimer wrote:
 Don Clugston wrote:
 
 I've been able to hack an implementation together. The 
 qualifiednameof!(X) metafunction gives
 the mangled fully qualified name of the symbol X, which includes the 
 complete name and some type information. Works for any symbol which is 
 permitted as a template alias parameter (ie, won't work for module 
 names, member variables, or local variables. But it does work for any 
 type, template, function, global or static variable).
Addition: I just discovered that it works for module names. It doesn't work for template aliases, though. It relies on the
 current name-mangling algorithm, but at least that is now documented.

 http://svn.dsource.org/projects/ddl/trunk/meta/qualifiedname.d
 Don,
 
 While I am very impressed at how you managed to do this, I am somewhat 
 disturbed to see the gymnastics it took to get there.  It shouldn't be 
 that hard to do.  If the D compiler had a simple command, property or 
 whatever in place to accomplish the same task, we wouldn't have to go to 
 such trouble.  
I agree. It's an exploration of what is _possible_. I'm using it to work out what you could do with such a feature. It seems that finding a way to hack a cool feature into the language is a good way of motivating Walter to provide a clean way of doing it <g>. It also helps to clarify how the feature needs to work. I was going to use the code in a project... but I'm a
 little hesitant to do so at the moment.
It's certainly not ready for production. In fact I haven't released any of 'meta'. I plan on refactoring most of it into a 'meta.demangle' (equivalent to std.demangle), at which point it might look more reasonable.
 I just about went cross-eyed trying to figure out how you managed that! 
 lol! (in fact, I never did figure it out).
I updated the code, and included some comments which should make it clearer.
 I think D history will forever remember you as the "template ninja."
<g> I'm just borrowing the mantle while Matthew is sleeping. I still feel like a D template novice. I still don't have much idea of what the limits are for what's possible. I've never used a mixin, an is() expression, or any kind of template constraint. If you get in first, you make all the easy discoveries. (And you have the most fun). I'm sure all kinds of crazy stuff is still waiting to be found.
Jan 20 2006
parent Garett Bass <garettbass studiotekne.com> writes:
Wow, Don, it hasn't totally sunk in yet, but that is impressive!  My original
goal was to use the string-ized identifier names in my serialization
primitives.  The idea is to prevent people from typing the identifier twice,
the second time as a string, which could introduce errors.  I also need the
strings to disambiguate subtypes in a super-typed array.

Fortunately/Unfortunately, school has begun again, and I have several huge
semester-long C/C++ projects, so it looks as though I won't be able to finish
the serialization primitives until Summer.  I'll try to find some time though,
because they work really well already, and they just need to go that extra
polymorphic mile...

Regards,
Garett

Don Clugston wrote:
 John Reimer wrote:
 Don Clugston wrote:

 I've been able to hack an implementation together. The 
 qualifiednameof!(X) metafunction gives
 the mangled fully qualified name of the symbol X, which includes the 
 complete name and some type information. Works for any symbol which 
 is permitted as a template alias parameter (ie, won't work for module 
 names, member variables, or local variables. But it does work for any 
 type, template, function, global or static variable).
Addition: I just discovered that it works for module names. It doesn't work for template aliases, though. It relies on the
 current name-mangling algorithm, but at least that is now documented.

 http://svn.dsource.org/projects/ddl/trunk/meta/qualifiedname.d
 Don,

 While I am very impressed at how you managed to do this, I am somewhat 
 disturbed to see the gymnastics it took to get there.  It shouldn't be 
 that hard to do.  If the D compiler had a simple command, property or 
 whatever in place to accomplish the same task, we wouldn't have to go 
 to such trouble.  
I agree. It's an exploration of what is _possible_. I'm using it to work out what you could do with such a feature. It seems that finding a way to hack a cool feature into the language is a good way of motivating Walter to provide a clean way of doing it <g>. It also helps to clarify how the feature needs to work. I was going to use the code in a project... but I'm a
 little hesitant to do so at the moment.
It's certainly not ready for production. In fact I haven't released any of 'meta'. I plan on refactoring most of it into a 'meta.demangle' (equivalent to std.demangle), at which point it might look more reasonable.
 I just about went cross-eyed trying to figure out how you managed 
 that! lol! (in fact, I never did figure it out).
I updated the code, and included some comments which should make it clearer.
 I think D history will forever remember you as the "template ninja."
<g> I'm just borrowing the mantle while Matthew is sleeping. I still feel like a D template novice. I still don't have much idea of what the limits are for what's possible. I've never used a mixin, an is() expression, or any kind of template constraint. If you get in first, you make all the easy discoveries. (And you have the most fun). I'm sure all kinds of crazy stuff is still waiting to be found.
Jan 22 2006
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Garett Bass wrote:
 Is there any template means by which I can create a string 
 representation from an identifier name at compile time?  I.e. given the 
 identifier name i, I'd like a template that can create a string "i".  
 Thanks in advance for any ideas.
 
 Regards,
 Garett
Well, I have an idea. You can get a string representation of class names, i.e., for a given class A, you can do this: import std.stdio; class A { } int main() { A a = new A(); char[] str = a.classinfo.name; writefln(str); return 0; } will print A to the screen. I don't know if this can exploited to create a work around for "stringizing" an identifier. Templates are not my area ..
Jan 13 2006
parent reply John Reimer <terminal.node gmail.com> writes:
Hasan Aljudy wrote:
 Garett Bass wrote:
 Is there any template means by which I can create a string 
 representation from an identifier name at compile time?  I.e. given 
 the identifier name i, I'd like a template that can create a string 
 "i".  Thanks in advance for any ideas.

 Regards,
 Garett
Well, I have an idea. You can get a string representation of class names, i.e., for a given class A, you can do this: import std.stdio; class A { } int main() { A a = new A(); char[] str = a.classinfo.name; writefln(str); return 0; } will print A to the screen. I don't know if this can exploited to create a work around for "stringizing" an identifier. Templates are not my area ..
The classinfo.name property is a feature for classes only (as the property name implies). You can't do anything like that for functions, methods, or variables. -JJR
Jan 13 2006
next sibling parent John Reimer <terminal.node gmail.com> writes:
John Reimer wrote:
 Hasan Aljudy wrote:
 Garett Bass wrote:
 Is there any template means by which I can create a string 
 representation from an identifier name at compile time?  I.e. given 
 the identifier name i, I'd like a template that can create a string 
 "i".  Thanks in advance for any ideas.

 Regards,
 Garett
Well, I have an idea. You can get a string representation of class names, i.e., for a given class A, you can do this: import std.stdio; class A { } int main() { A a = new A(); char[] str = a.classinfo.name; writefln(str); return 0; } will print A to the screen. I don't know if this can exploited to create a work around for "stringizing" an identifier. Templates are not my area ..
The classinfo.name property is a feature for classes only (as the property name implies). You can't do anything like that for functions, methods, or variables. -JJR
Although... you /can/ get the "type" name of a variable converted to a string from its id.
Jan 13 2006
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
John Reimer wrote:
 Hasan Aljudy wrote:
 
 Garett Bass wrote:

 Is there any template means by which I can create a string 
 representation from an identifier name at compile time?  I.e. given 
 the identifier name i, I'd like a template that can create a string 
 "i".  Thanks in advance for any ideas.

 Regards,
 Garett
Well, I have an idea. You can get a string representation of class names, i.e., for a given class A, you can do this: import std.stdio; class A { } int main() { A a = new A(); char[] str = a.classinfo.name; writefln(str); return 0; } will print A to the screen. I don't know if this can exploited to create a work around for "stringizing" an identifier. Templates are not my area ..
The classinfo.name property is a feature for classes only (as the property name implies). You can't do anything like that for functions, methods, or variables. -JJR
I was thinking more of creating a class inside the template, where the class name will be the supplied parameter (identifier). I guess that isn't possible .. is it?
Jan 14 2006
parent reply pragma <pragma_member pathlink.com> writes:
I was thinking more of creating a class inside the template, where the 
class name will be the supplied parameter (identifier).
I guess that isn't possible .. is it?
Do you mean like reflection? We're not quite there yet, but there is considerable demand for such a feature: you're not alone. - EricAnderton at yahoo
Jan 14 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
pragma wrote:
I was thinking more of creating a class inside the template, where the 
class name will be the supplied parameter (identifier).
I guess that isn't possible .. is it?
Do you mean like reflection? We're not quite there yet, but there is considerable demand for such a feature: you're not alone. - EricAnderton at yahoo
Not really, I was thinking in terms of template .. i.e. template createclass( T ) { class T { } } ... mixin createclass!( ANewClassName ); //create a class called ANewClassName but I discovered that it's not possible in D.
Jan 14 2006
next sibling parent Lars Ivar Igesund <larsivar igesund.net> writes:
Hasan Aljudy wrote:

 pragma wrote:
I was thinking more of creating a class inside the template, where the
class name will be the supplied parameter (identifier).
I guess that isn't possible .. is it?
Do you mean like reflection? We're not quite there yet, but there is considerable demand for such a feature: you're not alone. - EricAnderton at yahoo
Not really, I was thinking in terms of template .. i.e. template createclass( T ) { class T { } } ... mixin createclass!( ANewClassName ); //create a class called ANewClassName but I discovered that it's not possible in D.
I'm not really into templates yet, but have you tried alias parameters for that? Lars Ivar Igesund
Jan 14 2006
prev sibling parent reply Don Clugston <dac nospam.com.au> writes:
Hasan Aljudy wrote:
 pragma wrote:
 
 I was thinking more of creating a class inside the template, where 
 the class name will be the supplied parameter (identifier).
 I guess that isn't possible .. is it?
Do you mean like reflection? We're not quite there yet, but there is considerable demand for such a feature: you're not alone. - EricAnderton at yahoo
Not really, I was thinking in terms of template .. i.e. template createclass( T ) { class T { } } ... mixin createclass!( ANewClassName ); //create a class called ANewClassName but I discovered that it's not possible in D.
In general it's not possible. There's an interesting case where it is possible, but you have to do it manually: template createclass(char [] name) { static if (name[0]=='a') { class a { } else static if (name[0]=='b') { class b { } else static if (name[0]=='c') { class c { } } else static assert(0); // name not supported } mixin createclass!("a"); Of course, this is not much use. But it is an argument that a more general facility could be provided in the language without causing new problems. If the next line of code was a.somefunc(); an intellisense IDE is going to have a lot of trouble making sense of a. Since this problem already exists, it should reduce objection to the following proposal: I'd like to see the definition of Identifier changed to: Identifier: IdentifierStart IdentifierStart IdentifierChars identifier(StringLiteral) so that whereever you write abc you could also write identifier("abc") During the semantic pass, whenever identifier( _stringexpr_ ) is encountered, it would be replaced with _stringexpr_. In your case, it would let you write class identifier("ANewClassName") { } identifier("ANewClassName") identifier("x") = new identifier("ANewClassName"); Which would be completely useless, except that D provides compile-time string processing, so that the string literals could be created from constant strings. We'd have the equivalent of the C/C++ 'stringize' preprocessor operator, but fully integrated into the template system, and without wrecking the lexical and syntactic passes. Just need a 'tokenize' operator -- eg qualifiednameof(Identifier) eg const char [] y = qualifiednameof(x); static assert( y == "somemodule.SomeClass.someFunc.x"); This would mean that D templates would finally encompass all the functionality of the C++ preprocessor. A future step would be to add const char [][] membersof(Identifier) returning an array of all the names which were declared in the scope of Identifier. (although, this last one would not be useful until D gets array literals). Then we'd have full compile-time reflection, and the ability to dump arbitrary code into the optimiser based on the results. Undoubtedly far too much rope. :-)
Jan 16 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Whoa .. hold on there!
The class idea was a *hack* only! The real solution is not to integrate 
that "hack" into the language, but to add a way to convert an identifier 
name to a string at compile time, which should be easy for the compiler 
to do!!

I mean .. why would you want to convert a string to an identifier .. 
only to convert it back to a string again!!


Don Clugston wrote:
 Hasan Aljudy wrote:
 
 pragma wrote:

 I was thinking more of creating a class inside the template, where 
 the class name will be the supplied parameter (identifier).
 I guess that isn't possible .. is it?
Do you mean like reflection? We're not quite there yet, but there is considerable demand for such a feature: you're not alone. - EricAnderton at yahoo
Not really, I was thinking in terms of template .. i.e. template createclass( T ) { class T { } } ... mixin createclass!( ANewClassName ); //create a class called ANewClassName but I discovered that it's not possible in D.
In general it's not possible. There's an interesting case where it is possible, but you have to do it manually: template createclass(char [] name) { static if (name[0]=='a') { class a { } else static if (name[0]=='b') { class b { } else static if (name[0]=='c') { class c { } } else static assert(0); // name not supported } mixin createclass!("a"); Of course, this is not much use. But it is an argument that a more general facility could be provided in the language without causing new problems. If the next line of code was a.somefunc(); an intellisense IDE is going to have a lot of trouble making sense of a. Since this problem already exists, it should reduce objection to the following proposal: I'd like to see the definition of Identifier changed to: Identifier: IdentifierStart IdentifierStart IdentifierChars identifier(StringLiteral) so that whereever you write abc you could also write identifier("abc") During the semantic pass, whenever identifier( _stringexpr_ ) is encountered, it would be replaced with _stringexpr_. In your case, it would let you write class identifier("ANewClassName") { } identifier("ANewClassName") identifier("x") = new identifier("ANewClassName"); Which would be completely useless, except that D provides compile-time string processing, so that the string literals could be created from constant strings. We'd have the equivalent of the C/C++ 'stringize' preprocessor operator, but fully integrated into the template system, and without wrecking the lexical and syntactic passes. Just need a 'tokenize' operator -- eg qualifiednameof(Identifier) eg const char [] y = qualifiednameof(x); static assert( y == "somemodule.SomeClass.someFunc.x"); This would mean that D templates would finally encompass all the functionality of the C++ preprocessor. A future step would be to add const char [][] membersof(Identifier) returning an array of all the names which were declared in the scope of Identifier. (although, this last one would not be useful until D gets array literals). Then we'd have full compile-time reflection, and the ability to dump arbitrary code into the optimiser based on the results. Undoubtedly far too much rope. :-)
Jan 16 2006
parent Don Clugston <dac nospam.com.au> writes:
Hasan Aljudy wrote:
 Whoa .. hold on there!
 The class idea was a *hack* only! The real solution is not to integrate 
 that "hack" into the language, but to add a way to convert an identifier 
 name to a string at compile time, which should be easy for the compiler 
 to do!!
Yes, that's the purpose of the suggested qualifiednameof() operator, which is far less controversial than my other suggestion. I got a bit carried away, because I've been thinking about the general case -- how could D provide ALL the capabilities of the C++ preprocessor?
 I mean .. why would you want to convert a string to an identifier .. 
 only to convert it back to a string again!!
You wouldn't. But you might might convert an identifier to a string, manipulate the string, then convert it to another identifier. For example, module somemodule; int somefunc() { real x; const char [] s = qualifiednameof(x); // assert(s == "somemodule.somefunc.x") // Extract the name of the enclosing function const char [] selffuncname = split!(s, '.', 1); // assert(selffuncname == "somefunc") // Now get a function pointer to ourself... int function () selfptr = &__identifier(selffuncname); } Not a very sensible example. I'm just trying to illustrate that these functions would provide compile-time reflection. ( split!() is a function from my meta.string metaprogramming library; it behaves exactly like std.string.split, except that it works at compile time). Something like qualifiednameof() I think would be generally useful (apart from sophisticated uses, it would be great for error messages). And it seems to be harmless. (However, the __identifier() thing requires more thought, because it would be an extremely powerful and dangerous feature).
 
 Don Clugston wrote:
 
 Hasan Aljudy wrote:

 pragma wrote:

 I was thinking more of creating a class inside the template, where 
 the class name will be the supplied parameter (identifier).
 I guess that isn't possible .. is it?
Do you mean like reflection? We're not quite there yet, but there is considerable demand for such a feature: you're not alone. - EricAnderton at yahoo
Not really, I was thinking in terms of template .. i.e. template createclass( T ) { class T { } } ... mixin createclass!( ANewClassName ); //create a class called ANewClassName but I discovered that it's not possible in D.
In general it's not possible. There's an interesting case where it is possible, but you have to do it manually: template createclass(char [] name) { static if (name[0]=='a') { class a { } else static if (name[0]=='b') { class b { } else static if (name[0]=='c') { class c { } } else static assert(0); // name not supported } mixin createclass!("a"); Of course, this is not much use. But it is an argument that a more general facility could be provided in the language without causing new problems. If the next line of code was a.somefunc(); an intellisense IDE is going to have a lot of trouble making sense of a. Since this problem already exists, it should reduce objection to the following proposal: I'd like to see the definition of Identifier changed to: Identifier: IdentifierStart IdentifierStart IdentifierChars identifier(StringLiteral) so that whereever you write abc you could also write identifier("abc") During the semantic pass, whenever identifier( _stringexpr_ ) is encountered, it would be replaced with _stringexpr_. In your case, it would let you write class identifier("ANewClassName") { } identifier("ANewClassName") identifier("x") = new identifier("ANewClassName"); Which would be completely useless, except that D provides compile-time string processing, so that the string literals could be created from constant strings. We'd have the equivalent of the C/C++ 'stringize' preprocessor operator, but fully integrated into the template system, and without wrecking the lexical and syntactic passes. Just need a 'tokenize' operator -- eg qualifiednameof(Identifier) eg const char [] y = qualifiednameof(x); static assert( y == "somemodule.SomeClass.someFunc.x"); This would mean that D templates would finally encompass all the functionality of the C++ preprocessor. A future step would be to add const char [][] membersof(Identifier) returning an array of all the names which were declared in the scope of Identifier. (although, this last one would not be useful until D gets array literals). Then we'd have full compile-time reflection, and the ability to dump arbitrary code into the optimiser based on the results. Undoubtedly far too much rope. :-)
Jan 17 2006