Thread overview
Workaround for https://issues.dlang.org/show_bug.cgi?id=18422?
Feb 11, 2018
Seb
Feb 11, 2018
Adam D. Ruppe
Feb 11, 2018
John Colvin
Feb 11, 2018
Meta
[OT] - Re: Workaround for https://issues.dlang.org/show_bug.cgi?id=18422?
Feb 13, 2018
Nick Treleaven
February 11, 2018
I'm trying to sketch a simple compile-time reflection system, and https://issues.dlang.org/show_bug.cgi?id=18422 is a blocker of the entire approach. My intent is to have a struct Module, which can be initialized with a module name; then:

struct Module
{
    private string name;
    Data[] data(); // all data declarations
    Function[] functions();
    Struct[] structs();
    Class[] classes();
    Union[] unions();
    Enum[] enums();
}

Then each of those types carries the appropriate information. Notably, there are no templates involved, although all code is evaluated during compilation. Non-data information (types, qualifiers etc) is carried as strings. This allows for simple arrays to convey heterogeneous information such as "all functions in this module", even though their signatures are different.

This makes for a simple and easy to use system for introspecting things during compilation. Clearly in order to do that some of these compile-time strings must be mixed in, which is why https://issues.dlang.org/show_bug.cgi?id=18422 is so problematic.

Until we discuss a fix, are there any workarounds?


Thanks,

Andrei
February 11, 2018
On Sunday, 11 February 2018 at 15:34:07 UTC, Andrei Alexandrescu wrote:
> I'm trying to sketch a simple compile-time reflection system, and https://issues.dlang.org/show_bug.cgi?id=18422 is a blocker of the entire approach. My intent is to have a struct Module, which can be initialized with a module name; then:
>
> struct Module
> {
>     private string name;
>     Data[] data(); // all data declarations
>     Function[] functions();
>     Struct[] structs();
>     Class[] classes();
>     Union[] unions();
>     Enum[] enums();
> }
>
> Then each of those types carries the appropriate information. Notably, there are no templates involved, although all code is evaluated during compilation. Non-data information (types, qualifiers etc) is carried as strings. This allows for simple arrays to convey heterogeneous information such as "all functions in this module", even though their signatures are different.
>
> This makes for a simple and easy to use system for introspecting things during compilation. Clearly in order to do that some of these compile-time strings must be mixed in, which is why https://issues.dlang.org/show_bug.cgi?id=18422 is so problematic.
>
> Until we discuss a fix, are there any workarounds?
>
>
> Thanks,
>
> Andrei

Here's a workaround:

---
auto moduleSys(string name)()
{
    static struct Module
    {
        auto allMembers()
        {
            import std.range : only;
            assert(__ctfe);
            mixin("static import " ~ name ~ ";");
            return only(mixin("__traits(allMembers, " ~ name ~ ")"));
        }
    }
    return Module();
}

unittest
{
    enum x = moduleSys!"std.typecons".allMembers;
    pragma(msg, x);
}
---


https://run.dlang.io/is/t8KPfq
February 11, 2018
On Sunday, 11 February 2018 at 15:34:07 UTC, Andrei Alexandrescu wrote:
> My intent is to have a struct Module, which can be initialized with a module name; then:

The way I do this is to define the data structures kinda like you did, but then have a ctfe/template factory function to return it.

struct Module {
   string name;
   Data[] data;
  // etc
}

Module getModule(string name)() {
      Module mod;
      // populate here using template arg
      mod.name = name;
      mod.data = [__traits(allMembers, mixin(name))];
      // etc
      // return the simple struct
      return mod;
}


Then you can enum it individually:

enum x = getModule!"std.typecons";

and also runtime initialize it and put in an array:

Module[] allModules;

static this() {
   allModules ~= getModule!(__MODULE__);
}




This runtime data, compile time factory pattern I think solves everything you want without language changes. Is there anything about it you don't like?

February 11, 2018
On Sunday, 11 February 2018 at 15:34:07 UTC, Andrei Alexandrescu wrote:
> I'm trying to sketch a simple compile-time reflection system, and https://issues.dlang.org/show_bug.cgi?id=18422 is a blocker of the entire approach. My intent is to have a struct Module, which can be initialized with a module name; then:
>
> struct Module
> {
>     private string name;
>     Data[] data(); // all data declarations
>     Function[] functions();
>     Struct[] structs();
>     Class[] classes();
>     Union[] unions();
>     Enum[] enums();
> }
>
> Then each of those types carries the appropriate information. Notably, there are no templates involved, although all code is evaluated during compilation. Non-data information (types, qualifiers etc) is carried as strings. This allows for simple arrays to convey heterogeneous information such as "all functions in this module", even though their signatures are different.
>
> This makes for a simple and easy to use system for introspecting things during compilation. Clearly in order to do that some of these compile-time strings must be mixed in, which is why https://issues.dlang.org/show_bug.cgi?id=18422 is so problematic.
>
> Until we discuss a fix, are there any workarounds?
>
>
> Thanks,
>
> Andrei

I'm not 100% sure I follow what you need, but maybe one of these two will help:

`interface FunctionBase` and `class Function(string name) : FunctionBase`.

or

Use a templated constructor `this(string name)()`, so the fields are filled during ctfe using "template-time" information. This way the type stays the same.
February 11, 2018
On Sunday, 11 February 2018 at 15:34:07 UTC, Andrei Alexandrescu wrote:
> I'm trying to sketch a simple compile-time reflection system, and https://issues.dlang.org/show_bug.cgi?id=18422 is a blocker of the entire approach. My intent is to have a struct Module, which can be initialized with a module name; then:
>
> struct Module
> {
>     private string name;
>     Data[] data(); // all data declarations
>     Function[] functions();
>     Struct[] structs();
>     Class[] classes();
>     Union[] unions();
>     Enum[] enums();
> }
>
> Then each of those types carries the appropriate information. Notably, there are no templates involved, although all code is evaluated during compilation. Non-data information (types, qualifiers etc) is carried as strings. This allows for simple arrays to convey heterogeneous information such as "all functions in this module", even though their signatures are different.
>
> This makes for a simple and easy to use system for introspecting things during compilation. Clearly in order to do that some of these compile-time strings must be mixed in, which is why https://issues.dlang.org/show_bug.cgi?id=18422 is so problematic.
>
> Until we discuss a fix, are there any workarounds?
>
>
> Thanks,
>
> Andrei

If you need a workaround that doesn't have a struct or function templated on `name`, then no, I don't think there is. The problem is that there are two different kinds of compile time:

https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
February 13, 2018
On Sunday, 11 February 2018 at 15:34:07 UTC, Andrei Alexandrescu wrote:
> I'm trying to sketch a simple compile-time reflection system, and https://issues.dlang.org/show_bug.cgi?id=18422 is a blocker of the entire approach.

BTW please write a descriptive subject, not a bug ID. The #dbugfix posts of late without description make it annoying to browse the newsgroup - thanks!