Re: modules and mains
On Sunday, 22 August 2021 at 04:38:58 UTC, Ali Çehreli wrote: On 8/21/21 8:46 PM, Brian Tiffin wrote: > prompt$ cat B.d > module B; > version = boss; A cannot know about 'version' condition inside B. The solution is to provide version on the command line. This is how I do it with dmd: $ dmd -version=boss [...] (So, remove 'version = boss;' line in B.d) > But I'm getting a link error from gdc > > ``` > prompt$ gdc -o B B.d > /tmp/ccWg1BrF.o: In function `_Dmain': > B.d:(.text+0x52): undefined reference to `_D1A7commandFAAyaZi' > collect2: error: ld returned 1 exit status > ``` > > Is it just wrong thinking and *try again, ya noob*? ;-) Never! :) D modules work both like C's .h files and .c files. (Well, more like C++'s .h files because templates don't need .cpp part.) We import for declarations but we must also include for linking. Again, this is how it works with dmd: $ dmd B.d A.d -version=boss Another option is to use dmd's -i switch, which automatically includes modules for linking but I don't have experience with it other than it works: $ dmd B.d -version=boss -i (-i can take a pattern as well.) Ali Got it working with `gdc`. It makes some sense to list all the modules when compiling Boss, and separately when getting the sub-commands to each define a main, so I may explore this path some more. But I have the memory of a ~~5~~8 year old, so I'll be creating a Makefile as an aid. Was wistfully thinking I might be able to avoid Makefiles with D projects. ```make # Trying gdc with multiple modules .RECIPEPREFIX = > A: A.d gdc-11 -o A A.d B: A.d B.d gdc-11 -fversion=boss B.d A.d ``` which gives ``` prompt$ make A gdc-11 -o A A.d prompt$ make B gdc-11 -fversion=boss B.d A.d ``` and ``` prompt$ ./A one ["./A", "one"] prompt$ ./B ["Boss calling A"] ``` *A gets a car, and B gets a car, everybody gets a car.* This will get more fun as the real sub-commands get built up now. The plan is a support tool for COBOL development. Pump out named source fragments and project setups, keep Time and Task logs, automate Fossil commits, and the like. Each component usable on its own, with the main boss app, hopper. A little backfill, Grace Hopper was the defacto grand-ma of COBOL, one of the first humans to realize that computers could be used to compile "programs" and not just math formulas. She was also known as the oldest serving member in the U.S. Navy at the time she retired as a Rear admiral. As Zach Weinersmith once cartooned in SMBC, "You may not know me, but you should fear me". ;-) Thanks, Ali. Have good, make well
Re: std.stdio.File is throwing with the message of: "Access Violation"
On Saturday, 21 August 2021 at 23:50:51 UTC, Ruby The Roobster wrote: On Saturday, 21 August 2021 at 23:50:08 UTC, Ruby The Roobster wrote: On Saturday, 21 August 2021 at 06:08:17 UTC, evilrat wrote: First parameter for CreateWindow should be window class string that you used in wndclass.lpszClassName = appName.toUTF16z; Fix: wndclass.lpszClassName = "Test"; //May need casting... Anyways, this isn't an issue anymore. I'm just not gonna use Win32 API. Of course this is the "fix", but your example works fine and opens a file when window is created. What I don't really understand is why you are trying to remove import core.sys.windows.windows which contains declarations for HWND, HINSTANCE and family... It simply won't compile without it.
Re: implimenting interface function by inheriting from other class
On Sunday, 22 August 2021 at 01:14:08 UTC, Alexey wrote: On Saturday, 21 August 2021 at 20:35:43 UTC, Alexey wrote: Hello ```D interface Int { void coolFunc(); } class C1 { void coolFunc() { return; } } class C2 : C1, Int { } void main() { auto c = new C2; } ``` dmd says it's not Ok: t.d(14): Error: class `t.C2` interface function `void coolFunc()` is not implemented how to make dmd happy? we're with friends tried similar thing with c++, java, groovy and go - worked ok. ```Java interface Int { public void coolFunc(); }; class C1 { public void coolFunc() { return; } }; class C2 extends C1 implements Int { }; public class Main { public static void main(String args[]) { Int c = new C2(); } } ``` ```Groovy interface Int { void coolFunc() } class C1 { void coolFunc() { print "hello" } } class C2 extends C1 implements Int { } def printHello = { Int a -> a.coolFunc(); print " world: accept $Int" } C2 a = new C2() printHello(a) ``` ```C++ class Int; class C1; class C2; class Int { public: virtual void coolFunc() = delete; }; class C1 { public: virtual void coolFunc() { return; } }; class C2 : public C1, public Int { public: }; int main(int argc, char* argv[]) { auto c = new C2; } ``` ```Go package main import "fmt" type Int interface { CoolFunc() } type C1 struct { } func (self *C1) CoolFunc() { fmt.Println("worked") return } type C2 struct { C1 } func main() { var c Int c = new(C2) c.CoolFunc() } ``` Sorry, Bastiaan's solution is the only that I know of as well. Here's your desired behaviour: ```d import std.stdio:writeln; interface Int { void coolFunc(); } class C1 { void coolFunc() { { auto obj = (cast(C1)(cast(Int) this)); if (obj !is null) { do_one_thing(); } } { auto obj = (cast(C2)(cast(Int) this)); if (obj !is null) { obj.do_another_thing(); } } { auto obj = (cast(C3)(cast(Int) this)); if (obj !is null) { obj.do_something_else(); } } return; } void do_one_thing(){ writeln("one thing from C1"); } } class C2 : C1, Int { override void coolFunc(){ typeof(super).coolFunc(); } void do_another_thing(){ writeln("did another thing from C2"); } } class C3 : C1, Int { override void coolFunc(){ typeof(super).coolFunc(); } void do_something_else(){ writeln("doing something else from C3"); } } class C4 : C1, Int { override void coolFunc(){ typeof(super).coolFunc(); } } void main() { auto c = new C2; c.coolFunc(); } ```
Re: modules and mains
On 8/21/21 8:46 PM, Brian Tiffin wrote: > prompt$ cat B.d > module B; > version = boss; A cannot know about 'version' condition inside B. The solution is to provide version on the command line. This is how I do it with dmd: $ dmd -version=boss [...] (So, remove 'version = boss;' line in B.d) > But I'm getting a link error from gdc > > ``` > prompt$ gdc -o B B.d > /tmp/ccWg1BrF.o: In function `_Dmain': > B.d:(.text+0x52): undefined reference to `_D1A7commandFAAyaZi' > collect2: error: ld returned 1 exit status > ``` > > Is it just wrong thinking and *try again, ya noob*? ;-) Never! :) D modules work both like C's .h files and .c files. (Well, more like C++'s .h files because templates don't need .cpp part.) We import for declarations but we must also include for linking. Again, this is how it works with dmd: $ dmd B.d A.d -version=boss Another option is to use dmd's -i switch, which automatically includes modules for linking but I don't have experience with it other than it works: $ dmd B.d -version=boss -i (-i can take a pattern as well.) Ali
Re: modules and mains
On Sunday, 22 August 2021 at 03:22:02 UTC, Brian Tiffin wrote: Is this wrong thinking? I'm ~~working on~~ playing with a first project. Meant to be a suite of tools, each usable from the command line, i.e. with a `main`. Then a manager program that accepts subcommands for dispatch *and other boss type things*. boss.d wants to import command1.d command2.d etc. Is there a way for `command1.d` to know it's an `import` versus a file named as part of a `gdc` compile? I'd like to skip defining `main` during `import` (using a different name for boss dispatch), but do define `main` when it's a standalone compile. Or is that a bad way of thinking about D program development interactions? Cheers Tried this: ```d prompt$ cat A.d module A; version (boss) {} else { int main(string[] args) { return command(args); } } int command(string[] args) { import std.stdio: writeln; writeln(args); return 0; } ``` with ```d prompt$ cat B.d module B; version = boss; import A; int main(string[] args) { A.command(["Boss calling A"]); return 0; } ``` But I'm getting a link error from gdc ``` prompt$ gdc -o B B.d /tmp/ccWg1BrF.o: In function `_Dmain': B.d:(.text+0x52): undefined reference to `_D1A7commandFAAyaZi' collect2: error: ld returned 1 exit status ``` Is it just wrong thinking and *try again, ya noob*? ;-) Cheers again
modules and mains
Is this wrong thinking? I'm ~~working on~~ playing with a first project. Meant to be a suite of tools, each usable from the command line, i.e. with a `main`. Then a manager program that accepts subcommands for dispatch *and other boss type things*. boss.d wants to import command1.d command2.d etc. Is there a way for `command1.d` to know it's an `import` versus a file named as part of a `gdc` compile? I'd like to skip defining `main` during `import` (using a different name for boss dispatch), but do define `main` when it's a standalone compile. Or is that a bad way of thinking about D program development interactions? Cheers
Re: Unqualified class name
On Sunday, 22 August 2021 at 00:18:18 UTC, Ali Çehreli wrote: I did not read the linked thread but a "this template parameter" seems to work in this case: class Whoami { string name(this This)() const { return __traits(identifier, This); } } class AnotherOne : Whoami { } unittest { assert((new Whoami).name == "Whoami"); assert((new AnotherOne).name == "AnotherOne"); } void main() { } Ali That's not enough to make runtime dispatch out of static dispatch: ```d class Whoami { string name(this This)() const { return __traits(identifier, This); } string rtname() const { import std.path : extension; return typeid(this).name.extension[1 .. $]; } } class AnotherOne : Whoami { } unittest { import std.algorithm : map, equal; auto list = [new Whoami, new AnotherOne]; assert(list.map!(o => o.name).equal(["Whoami", "Whoami"])); assert(list.map!(o => o.rtname).equal(["Whoami", "AnotherOne"])); } ``` The next stage of complication is to have compiled library code that loops over Whoami[] getting some subtypes of Whoami that were defined unknowable to the library.
Re: implimenting interface function by inheriting from other class
On Saturday, 21 August 2021 at 20:35:43 UTC, Alexey wrote: Hello ```D interface Int { void coolFunc(); } class C1 { void coolFunc() { return; } } class C2 : C1, Int { } void main() { auto c = new C2; } ``` dmd says it's not Ok: t.d(14): Error: class `t.C2` interface function `void coolFunc()` is not implemented how to make dmd happy? we're with friends tried similar thing with c++, java, groovy and go - worked ok. ```Java interface Int { public void coolFunc(); }; class C1 { public void coolFunc() { return; } }; class C2 extends C1 implements Int { }; public class Main { public static void main(String args[]) { Int c = new C2(); } } ``` ```Groovy interface Int { void coolFunc() } class C1 { void coolFunc() { print "hello" } } class C2 extends C1 implements Int { } def printHello = { Int a -> a.coolFunc(); print " world: accept $Int" } C2 a = new C2() printHello(a) ``` ```C++ class Int; class C1; class C2; class Int { public: virtual void coolFunc() = delete; }; class C1 { public: virtual void coolFunc() { return; } }; class C2 : public C1, public Int { public: }; int main(int argc, char* argv[]) { auto c = new C2; } ``` ```Go package main import "fmt" type Int interface { CoolFunc() } type C1 struct { } func (self *C1) CoolFunc() { fmt.Println("worked") return } type C2 struct { C1 } func main() { var c Int c = new(C2) c.CoolFunc() } ```
Re: Unqualified class name
On 8/21/21 2:48 PM, jfondren wrote: On Saturday, 21 August 2021 at 21:13:58 UTC, Jeremy T. Gibson wrote: On Saturday, 21 August 2021 at 18:27:34 UTC, Ali Çehreli wrote: return __traits(identifier, typeof(this)); That works perfectly! Thanks. =) This is exactly the solution you linked to in your first post, and found wanting. ```d class Whoami { string name() { return __traits(identifier, typeof(this)); } } class AnotherOne : Whoami { } unittest { assert((new Whoami).name == "Whoami"); assert((new AnotherOne).name == "Whoami"); } ``` I did not read the linked thread but a "this template parameter" seems to work in this case: class Whoami { string name(this This)() const { return __traits(identifier, This); } } class AnotherOne : Whoami { } unittest { assert((new Whoami).name == "Whoami"); assert((new AnotherOne).name == "AnotherOne"); } void main() { } Ali
Re: std.stdio.File is throwing with the message of: "Access Violation"
On Saturday, 21 August 2021 at 23:50:08 UTC, Ruby The Roobster wrote: wndclass.lpszClassName = "Test"; //May need casting... don't cast it just use the w suffix wndclass.lpszClassName = "Test"w; casts are usually indicating a mistake
Re: std.stdio.File is throwing with the message of: "Access Violation"
On Saturday, 21 August 2021 at 06:08:17 UTC, evilrat wrote: First parameter for CreateWindow should be window class string that you used in wndclass.lpszClassName = appName.toUTF16z; Fix: wndclass.lpszClassName = "Test"; //May need casting...
Re: std.stdio.File is throwing with the message of: "Access Violation"
On Saturday, 21 August 2021 at 23:50:08 UTC, Ruby The Roobster wrote: On Saturday, 21 August 2021 at 06:08:17 UTC, evilrat wrote: First parameter for CreateWindow should be window class string that you used in wndclass.lpszClassName = appName.toUTF16z; Fix: wndclass.lpszClassName = "Test"; //May need casting... Anyways, this isn't an issue anymore. I'm just not gonna use Win32 API.
Re: implimenting interface function by inheriting from other class
On Saturday, 21 August 2021 at 23:14:14 UTC, Alexey wrote: I want `this` inside of C1::coolFunc to return C2 if called as C2::coolFunc so executing `cast(C2) this !is null` inside of C1::coolFunc would work If this would work, I'd farther used this like so ```D interface Int { void coolFunc(); } class C1 { void coolFunc() { { auto obj = (cast(C1)(cast(Int) this)); if (obj !is null) { do_one_thing(); } } { auto obj = (cast(C2)(cast(Int) this)); if (obj !is null) { do_another_thing(); } } { auto obj = (cast(C3)(cast(Int) this)); if (obj !is null) { do_something_else(); } } return; } } class C2 : C1, Int { } class C3 : C1, Int { } class C4 : C1, Int { } void main() { auto c = new C2; c.coolFunc(); } ```
Re: implimenting interface function by inheriting from other class
I want `this` inside of C1::coolFunc to return C2 if called as C2::coolFunc so executing `cast(C2) this !is null` inside of C1::coolFunc would work
Re: implimenting interface function by inheriting from other class
On Saturday, 21 August 2021 at 22:56:40 UTC, Bastiaan Veelo wrote: On Saturday, 21 August 2021 at 20:35:43 UTC, Alexey wrote: Hello ```D interface Int { void coolFunc(); } class C1 { void coolFunc() { return; } } class C2 : C1, Int { } void main() { auto c = new C2; } ``` dmd says it's not Ok: t.d(14): Error: class `t.C2` interface function `void coolFunc()` is not implemented how to make dmd happy? Not sure if this is the best way, but it does make dmd happy: https://run.dlang.io/is/44F3AE ```d class C2 : C1, Int { override void coolFunc() { C1.coolFunc; } } ``` It looks lame, I admit. — Bastiaan. I want `this` inside of C1::coolFunc to return C2 if called as C2::coolFunc
Re: implimenting interface function by inheriting from other class
On Saturday, 21 August 2021 at 20:35:43 UTC, Alexey wrote: Hello ```D interface Int { void coolFunc(); } class C1 { void coolFunc() { return; } } class C2 : C1, Int { } void main() { auto c = new C2; } ``` dmd says it's not Ok: t.d(14): Error: class `t.C2` interface function `void coolFunc()` is not implemented how to make dmd happy? Not sure if this is the best way, but it does make dmd happy: https://run.dlang.io/is/44F3AE ```d class C2 : C1, Int { override void coolFunc() { C1.coolFunc; } } ``` It looks lame, I admit. — Bastiaan.
Re: Unqualified class name
On Saturday, 21 August 2021 at 21:13:58 UTC, Jeremy T. Gibson wrote: On Saturday, 21 August 2021 at 18:27:34 UTC, Ali Çehreli wrote: return __traits(identifier, typeof(this)); That works perfectly! Thanks. =) This is exactly the solution you linked to in your first post, and found wanting. ```d class Whoami { string name() { return __traits(identifier, typeof(this)); } } class AnotherOne : Whoami { } unittest { assert((new Whoami).name == "Whoami"); assert((new AnotherOne).name == "Whoami"); } ```
Re: Unqualified class name
On Saturday, 21 August 2021 at 18:45:07 UTC, jfondren wrote: On Saturday, 21 August 2021 at 17:33:51 UTC, Jeremy T. Gibson wrote: is there a simple way to get the unqualified name of a class at runtime without having to pass it through std.format? `typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own. https://dlang.org/phobos/object.html#.TypeInfo_Class.name is all you have there, and it's just a string, so the simple way is to manipulate the string. string unqualified(string name) { import std.string : lastIndexOf; import std.algorithm : min; const i = name.lastIndexOf('.'); return i == -1 ? name : name[min(i+1, $) .. $]; Parsing was always an option, but anytime I come across a solution where parsing/formatting seems to be the answer, it always feels more hacky than a genuine solution. Hacks can be fine, especially in low-frequency code like the stuff I'm revisiting this month, but I always prefer direct library-based or language-based solutions whenever humanly possible. Dlang's reference docs unfortunately assume a level of expertise with the language (especially, expertise with code generation and compiler specs) that makes it much harder for me to "ask the right questions" when I'm searching: I'm really not much of a programmer. Heh.
Re: Unqualified class name
On Saturday, 21 August 2021 at 18:27:34 UTC, Ali Çehreli wrote: return __traits(identifier, typeof(this)); That works perfectly! Thanks. =)
implimenting interface function by inheriting from other class
Hello ```D interface Int { void coolFunc(); } class C1 { void coolFunc() { return; } } class C2 : C1, Int { } void main() { auto c = new C2; } ``` dmd says it's not Ok: t.d(14): Error: class `t.C2` interface function `void coolFunc()` is not implemented how to make dmd happy?
Re: Unqualified class name
On Saturday, 21 August 2021 at 17:33:51 UTC, Jeremy T. Gibson wrote: is there a simple way to get the unqualified name of a class at runtime without having to pass it through std.format? `typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own. https://dlang.org/phobos/object.html#.TypeInfo_Class.name is all you have there, and it's just a string, so the simple way is to manipulate the string. This seems a bit silly but I'm not worried about VMS 2.0 coming along and changing how extensions work ("nodot".extension == "" however, so if module-less classes are possible then this would fail with a RangeError): ```d class Whoami { string report() { import std.path : extension; return "class: " ~ typeid(this).name.extension[1..$]; } } class AnotherOne : Whoami {} unittest { assert((new Whoami).report == "class: Whoami"); assert((new AnotherOne).report == "class: AnotherOne"); } string unqualified(string name) { import std.string : lastIndexOf; import std.algorithm : min; const i = name.lastIndexOf('.'); return i == -1 ? name : name[min(i+1, $) .. $]; } unittest { assert(typeid(new Whoami).name.unqualified == "Whoami"); assert(typeid(new AnotherOne).name.unqualified == "AnotherOne"); assert("".unqualified == ""); assert("x".unqualified == "x"); assert("x.".unqualified == ""); } ```
Re: Unqualified class name
On 8/21/21 10:33 AM, Jeremy T. Gibson wrote: `typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own. I've been reminded of __traits(identifier) on this forum just yesterday: import std.stdio; class Coo { string name() const { return __traits(identifier, typeof(this)); } } void main() { auto c = new Coo(); writeln(c.name()); } Ali
Unqualified class name
I saw this thread -- https://forum.dlang.org/post/hdkvezicxfvehbtvj...@forum.dlang.org -- which works at compile time (although templating seems like overkill for my purpose), but is there a simple way to get the unqualified name of a class at runtime without having to pass it through std.format? `typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own. I'm currently using manually-assigned literals to store the name of each class, which seems... wrong. ;-) If it matters or makes things simpler, the class is attempting to report its own name in one of its own methods, rather than an external function attempting to deduce the name of an arbitrary object at runtime.
Re: Lexicographical object comparison by selected members of a struct
On Saturday, 21 August 2021 at 13:45:59 UTC, Ali Çehreli wrote: On 8/21/21 1:31 AM, Tejas wrote: > I was more impressed that you found that hack in the first place I can't take credit. :) 'static foreach' had that difference since its inception. The spec says "If a new scope is desired for each expansion, use another set of braces:" https://dlang.org/spec/version.html#staticforeach Ali I'm an inattentive dunce ;_;
Re: Lexicographical object comparison by selected members of a struct
On 8/21/21 1:31 AM, Tejas wrote: > I was more impressed that you found that hack in the first place I can't take credit. :) 'static foreach' had that difference since its inception. The spec says "If a new scope is desired for each expansion, use another set of braces:" https://dlang.org/spec/version.html#staticforeach Ali
Re: C to D convertor
On Saturday, 21 August 2021 at 08:59:55 UTC, evilrat wrote: On Saturday, 21 August 2021 at 08:14:22 UTC, Виталий Фадеев wrote: I know, i know... It not possible, but part of the C code we can to convert to the D. Show me, please, solutions, projects, tools, scripts, docs. Can you give the link ? `htod` is 1. Any more ? dstep https://code.dlang.org/packages/dstep dpp https://code.dlang.org/packages/dpp ohmygentool https://github.com/Superbelko/ohmygentool evilrat, thank you!
Re: C to D convertor
On Saturday, 21 August 2021 at 08:14:22 UTC, Виталий Фадеев wrote: I know, i know... It not possible, but part of the C code we can to convert to the D. Show me, please, solutions, projects, tools, scripts, docs. Can you give the link ? `htod` is 1. Any more ? dstep https://code.dlang.org/packages/dstep dpp https://code.dlang.org/packages/dpp ohmygentool https://github.com/Superbelko/ohmygentool
Re: Lexicographical object comparison by selected members of a struct
On Saturday, 21 August 2021 at 06:58:47 UTC, Ali Çehreli wrote: On 8/20/21 11:19 PM, Tejas wrote: [...] Yes. 'static foreach' does not introduce scope, which can be pretty useful. For example, one can define functions at module scope. The subtle differences between 'static foreach' and '(compile-time) foreach' can be surprising. For example, I don't understand why I can't use foreach (i; 0 .. members.length) { enum ident = __traits(identifier, members[i]); // ... } Error: variable `i` cannot be read at compile time. I think it should be. :) members.length is compile-time; so, 'i' should be compile time. And then, why can't 'static foreach' iterate over 'members'? static foreach (member; members) {{ // ... }} Error: value of `this` is not known at compile time Hm? Well, I am happy that there is always a path through. :) Ali Maybe it has something to do with that compile-time vs compile-time thing by quickfur on the dlang wiki. I was more impressed that you found that hack in the first place
C to D convertor
I know, i know... It not possible, but part of the C code we can to convert to the D. Show me, please, solutions, projects, tools, scripts, docs. Can you give the link ? Examples of what the wanted: // C typedef struct { uint32_t version; /* 0x5000 */ uint16_t num_glyphs; } MaxProTable; // D struct MaxProTable { uint32_t version; /* 0x5000 */ uint16_t num_glyphs; } // C #define ENABLE_SUBDIV 0 // D enum ENABLE_SUBDIV = 0; // C #include "triangulate.h" // D import triangulate; // C #include // D import core.stdc.string; // C #define cross2(a,b) ((a)[0]*(b)[1]-(a)[1]*(b)[0]) // D pragma( inline, true ) auto cross2( T1, T2 )( T1 a, T2 b ) { return ((a)[0]*(b)[1]-(a)[1]*(b)[0]); } // C double ab[2]; // D double[2] ab; // C trgu = calloc( 1, sizeof(*trgu) ); // D trgu = calloc( 1, (*trgu).sizeof ); // C PointFlag *point_flags = gt->flags; // D PointFlag *point_flags = gt.flags; `htod` is 1. Any more ?
Re: Lexicographical object comparison by selected members of a struct
On 8/20/21 11:19 PM, Tejas wrote: On Saturday, 21 August 2021 at 06:03:33 UTC, Ali Çehreli wrote: On 8/20/21 10:37 PM, Alexandru Ermicioi wrote: [...] Cool! Much better. :) I could not do [...] Did you use that double curly bracket in `static foreach` so that you don't get error for declaring stuff inside `static foreach` ? Yes. 'static foreach' does not introduce scope, which can be pretty useful. For example, one can define functions at module scope. The subtle differences between 'static foreach' and '(compile-time) foreach' can be surprising. For example, I don't understand why I can't use foreach (i; 0 .. members.length) { enum ident = __traits(identifier, members[i]); // ... } Error: variable `i` cannot be read at compile time. I think it should be. :) members.length is compile-time; so, 'i' should be compile time. And then, why can't 'static foreach' iterate over 'members'? static foreach (member; members) {{ // ... }} Error: value of `this` is not known at compile time Hm? Well, I am happy that there is always a path through. :) Ali