digitalmars.D - core.reflect vs c++ reflection
- Stefan Koch (33/33) Sep 26 2021 Good day,
- Stefan Koch (4/7) Sep 26 2021 is supposed to be:
- bauss (4/13) Sep 26 2021 What about E.stringof? Instead of hardcoding names :) Not sure if
- Stefan Koch (6/25) Sep 27 2021 E stringof would return the name of the type;
- bauss (4/32) Sep 27 2021 Yeah I figured it wouldn't work that easily.
- Stefan Koch (7/10) Sep 27 2021 Yes, but you can typo ThisTypeName whether you type it with
- WebFreak001 (8/20) Sep 27 2021 If it's mistyped, the compiler will complain that it doesn't exist
- Stefan Koch (8/16) Sep 27 2021 core.reflect will tell you that you tried to resolve a name which
- russhy (18/18) Sep 27 2021 using traits:
- Stefan Koch (6/24) Sep 28 2021 Yes the casting isn't great but all of that can be hidden with
- WebFreak001 (7/25) Sep 28 2021 maybe for `nodeFromName("T")` leave it unsolved but there could
- Stefan Koch (7/13) Sep 28 2021 I can provide a `NodeFromAlias`. But I don't want to promote such
- bauss (4/26) Sep 27 2021 Yeah, I really wish we had an alternative to stringof like
- Adam D Ruppe (4/7) Sep 28 2021 It is called
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (2/5) Sep 28 2021 Why is `.stringof` worse than `__traits(identifier)`?
- Alexandru Ermicioi (4/12) Sep 28 2021 Because traits identifier is well defined to return only the id
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (9/12) Sep 28 2021 Note that `.stringof` works in cases where `__traits(identifier)`
- Adam D Ruppe (5/7) Sep 28 2021 That's because a type has no identifier. And this is good anyway
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (2/6) Sep 28 2021 Can you elaborate on why you consider this being a bug?
- Adam D Ruppe (3/4) Sep 28 2021 https://forum.dlang.org/post/fbcltjuysmjrxmebeeva@forum.dlang.org
- bauss (4/11) Sep 28 2021 __traits(identifier) doesn't work either.
- Adam D Ruppe (3/6) Sep 28 2021 That's doing exactly what it is supposed to do. What did you
- bauss (5/13) Sep 28 2021 Yeah but the point in this case is to get "a" as a string.
Good day, It's hard to find good examples of the c++ reflection ts so I've copied one I've found in an earlier proposal I am just putting the proposed c++ syntax here, next to how my core.reflect library would handle this case. ```C #include <meta> template<Enum T> std::string to_string(T value) { // Could also be marked constexpr for constexpr (auto e : std::meta::members_of(reflexpr(T)) { if (exprid(e) == value) { return std::meta::name_of(e); } } return "<unnamed>"; } ``` ```D import core.reflect.reflect; string toString(E)(E enumValue) { static immutable ed = cast(EnumDeclaration)nodeFromName(E); foreach(m; ed.members) { if ((cast(IntegerLiteral)m.value).value == enumValue) { return m.name; } } return "unnamed"; } ``` Please let know what you think.
Sep 26 2021
On Sunday, 26 September 2021 at 19:03:24 UTC, Stefan Koch wrote:Good day,Please let know what you think.Ugh typo.static immutable ed = cast(EnumDeclaration)nodeFromName(E);is supposed to be: `static immutable ed = cast(EnumDeclaration)nodeFromName("E");`
Sep 26 2021
On Sunday, 26 September 2021 at 19:09:31 UTC, Stefan Koch wrote:On Sunday, 26 September 2021 at 19:03:24 UTC, Stefan Koch wrote:What about E.stringof? Instead of hardcoding names :) Not sure if stringof will return E in all cases, so obviously only if it works.Good day,Please let know what you think.Ugh typo.static immutable ed = cast(EnumDeclaration)nodeFromName(E);is supposed to be: `static immutable ed = cast(EnumDeclaration)nodeFromName("E");`
Sep 26 2021
On Monday, 27 September 2021 at 06:25:07 UTC, bauss wrote:On Sunday, 26 September 2021 at 19:09:31 UTC, Stefan Koch wrote:E stringof would return the name of the type; In simple cases and garbage in others. Whereas the name E always refers to the type used in the toString template. Also "E" is less typing than E.stringofOn Sunday, 26 September 2021 at 19:03:24 UTC, Stefan Koch wrote:What about E.stringof? Instead of hardcoding names :) Not sure if stringof will return E in all cases, so obviously only if it works.Good day,Please let know what you think.Ugh typo.static immutable ed = cast(EnumDeclaration)nodeFromName(E);is supposed to be: `static immutable ed = cast(EnumDeclaration)nodeFromName("E");`
Sep 27 2021
On Monday, 27 September 2021 at 07:28:46 UTC, Stefan Koch wrote:On Monday, 27 September 2021 at 06:25:07 UTC, bauss wrote:Yeah I figured it wouldn't work that easily. In this case yeah "E" wouldn't be a problem but if it was "ThisTypeName" you might end up with a typo.On Sunday, 26 September 2021 at 19:09:31 UTC, Stefan Koch wrote:E stringof would return the name of the type; In simple cases and garbage in others. Whereas the name E always refers to the type used in the toString template. Also "E" is less typing than E.stringofOn Sunday, 26 September 2021 at 19:03:24 UTC, Stefan Koch wrote:What about E.stringof? Instead of hardcoding names :) Not sure if stringof will return E in all cases, so obviously only if it works.Good day,Please let know what you think.Ugh typo.static immutable ed = cast(EnumDeclaration)nodeFromName(E);is supposed to be: `static immutable ed = cast(EnumDeclaration)nodeFromName("E");`
Sep 27 2021
On Monday, 27 September 2021 at 07:32:48 UTC, bauss wrote:Yeah I figured it wouldn't work that easily. In this case yeah "E" wouldn't be a problem but if it was "ThisTypeName" you might end up with a typo.Yes, but you can typo ThisTypeName whether you type it with quotes around it or without. It's still an identifier. Which may not be Identifying anything if it's mistyped. The reason why I am using a string is that I wanted to avoid having to introduce a special expression. see c++ `reflexpr`
Sep 27 2021
On Monday, 27 September 2021 at 08:39:45 UTC, Stefan Koch wrote:On Monday, 27 September 2021 at 07:32:48 UTC, bauss wrote:If it's mistyped, the compiler will complain that it doesn't exist When it's an identifier, IDE refactorings (automated renaming) will find it, while it wouldn't find it in a string, especially the more generic the name is (which is common for template types `T`) `nameof(Foo.T)` it also just returns `"T"`Yeah I figured it wouldn't work that easily. In this case yeah "E" wouldn't be a problem but if it was "ThisTypeName" you might end up with a typo.Yes, but you can typo ThisTypeName whether you type it with quotes around it or without. It's still an identifier. Which may not be Identifying anything if it's mistyped. The reason why I am using a string is that I wanted to avoid having to introduce a special expression. see c++ `reflexpr`
Sep 27 2021
On Monday, 27 September 2021 at 13:12:32 UTC, WebFreak001 wrote:If it's mistyped, the compiler will complain that it doesn't existcore.reflect will tell you that you tried to resolve a name which does not exist as well.When it's an identifier, IDE refactorings (automated renaming) will find it, while it wouldn't find it in a string, especially the more generic the name is (which is common for template types `T`) `nameof(Foo.T)` it also just returns `"T"`That's valid. I have to think about what to do about that. Maybe remove the "" for the refactoring? a simple search for `nodeFromName\(\"$ID\"\)` maybe? It's the only primitive in code reflect which does this.
Sep 27 2021
using traits: ```D string enum_to_str(E)(E v) if (is(E == enum)) { final switch (v) with(E) { static foreach (m; __traits(allMembers, E)) { case mixin(m): return m; } } } ``` core.reflect is nicer than traits because you actually get to use actual D code But the casting is kinda ugly, and it gives me java nightmares.. so the C++ actually feels much better
Sep 27 2021
On Monday, 27 September 2021 at 22:51:01 UTC, russhy wrote:using traits: ```D string enum_to_str(E)(E v) if (is(E == enum)) { final switch (v) with(E) { static foreach (m; __traits(allMembers, E)) { case mixin(m): return m; } } } ``` core.reflect is nicer than traits because you actually get to use actual D code But the casting is kinda ugly, and it gives me java nightmares.. so the C++ actually feels much betterYes the casting isn't great but all of that can be hidden with more library code. The class oriented design of core.reflect is the way it is because it mirrors internals rather closely at this point. I am open for improvement suggestions.
Sep 28 2021
On Monday, 27 September 2021 at 15:17:39 UTC, Stefan Koch wrote:On Monday, 27 September 2021 at 13:12:32 UTC, WebFreak001 wrote:maybe for `nodeFromName("T")` leave it unsolved but there could also be a `nodeFrom!T` which could additionally check for the type of T and return the correct node type (like EnumDeclaration from enums) This would additionally remove the need to do casts (and potentially mess up)If it's mistyped, the compiler will complain that it doesn't existcore.reflect will tell you that you tried to resolve a name which does not exist as well.When it's an identifier, IDE refactorings (automated renaming) will find it, while it wouldn't find it in a string, especially the more generic the name is (which is common for template types `T`) `nameof(Foo.T)` it also just returns `"T"`That's valid. I have to think about what to do about that. Maybe remove the "" for the refactoring? a simple search for `nodeFromName\(\"$ID\"\)` maybe? It's the only primitive in code reflect which does this.
Sep 28 2021
On Tuesday, 28 September 2021 at 07:10:43 UTC, WebFreak001 wrote:maybe for `nodeFromName("T")` leave it unsolved but there could also be a `nodeFrom!T` which could additionally check for the type of T and return the correct node type (like EnumDeclaration from enums) This would additionally remove the need to do casts (and potentially mess up)I can provide a `NodeFromAlias`. But I don't want to promote such use. I went through some of trouble to avoid static polymorphism. I have to admit it is though it is tempting to chose the more convenient. `node!bla` syntax.
Sep 28 2021
On Monday, 27 September 2021 at 13:12:32 UTC, WebFreak001 wrote:On Monday, 27 September 2021 at 08:39:45 UTC, Stefan Koch wrote:Yeah, I really wish we had an alternative to stringof like nameof. I often forgot that aliases don't work well with it, as displayed here :)On Monday, 27 September 2021 at 07:32:48 UTC, bauss wrote:If it's mistyped, the compiler will complain that it doesn't exist When it's an identifier, IDE refactorings (automated renaming) will find it, while it wouldn't find it in a string, especially the more generic the name is (which is common for template types `T`) `nameof(Foo.T)` it also just returns `"T"`Yeah I figured it wouldn't work that easily. In this case yeah "E" wouldn't be a problem but if it was "ThisTypeName" you might end up with a typo.Yes, but you can typo ThisTypeName whether you type it with quotes around it or without. It's still an identifier. Which may not be Identifying anything if it's mistyped. The reason why I am using a string is that I wanted to avoid having to introduce a special expression. see c++ `reflexpr`
Sep 27 2021
On Tuesday, 28 September 2021 at 06:43:39 UTC, bauss wrote:Yeah, I really wish we had an alternative to stringof like nameof. I often forgot that aliases don't work well with it, as displayed here :)It is called __traits(identifier) .stringof should never be used outside of debugging messages.
Sep 28 2021
On Tuesday, 28 September 2021 at 11:45:37 UTC, Adam D Ruppe wrote:It is called __traits(identifier) .stringof should never be used outside of debugging messages.Why is `.stringof` worse than `__traits(identifier)`?
Sep 28 2021
On Tuesday, 28 September 2021 at 12:32:04 UTC, Per Nordlöw wrote:On Tuesday, 28 September 2021 at 11:45:37 UTC, Adam D Ruppe wrote:Because traits identifier is well defined to return only the id of the subject, while stringof can return more than id. It can for example return the expression as a string.It is called __traits(identifier) .stringof should never be used outside of debugging messages.Why is `.stringof` worse than `__traits(identifier)`?
Sep 28 2021
On Tuesday, 28 September 2021 at 12:32:04 UTC, Per Nordlöw wrote:Note that `.stringof` works in cases where `__traits(identifier)` doesn't, such as in ```d alias S = string; pragma(msg, S.stringof); // ok, print `string` pragma(msg, __traits(identifier, S)); // fails ``` ..stringof should never be used outside of debugging messages.Why? And in what cases is`.stringof` worse than `__traits(identifier)`?
Sep 28 2021
On Tuesday, 28 September 2021 at 12:38:52 UTC, Per Nordlöw wrote:Note that `.stringof` works in cases where `__traits(identifier)` doesn't, such as inThat's because a type has no identifier. And this is good anyway because there's never a good reason to get a type as a string. It is a bug waiting to happen any time someone writes that, so making it an error is a good thing.
Sep 28 2021
On Tuesday, 28 September 2021 at 12:48:08 UTC, Adam D Ruppe wrote:That's because a type has no identifier. And this is good anyway because there's never a good reason to get a type as a string. It is a bug waiting to happen any time someone writes that, so making it an error is a good thing.Can you elaborate on why you consider this being a bug?
Sep 28 2021
On Tuesday, 28 September 2021 at 12:53:36 UTC, Per Nordlöw wrote:Can you elaborate on why you consider this being a bug?https://forum.dlang.org/post/fbcltjuysmjrxmebeeva forum.dlang.org https://stackoverflow.com/questions/32615733/struct-composition-with-mixin-and-templates/32621854#32621854
Sep 28 2021
On Tuesday, 28 September 2021 at 11:45:37 UTC, Adam D Ruppe wrote:On Tuesday, 28 September 2021 at 06:43:39 UTC, bauss wrote:__traits(identifier) doesn't work either. See: https://run.dlang.io/is/9cDdraYeah, I really wish we had an alternative to stringof like nameof. I often forgot that aliases don't work well with it, as displayed here :)It is called __traits(identifier) .stringof should never be used outside of debugging messages.
Sep 28 2021
On Tuesday, 28 September 2021 at 13:51:55 UTC, bauss wrote:__traits(identifier) doesn't work either. See: https://run.dlang.io/is/9cDdraThat's doing exactly what it is supposed to do. What did you expect and why do you want that?
Sep 28 2021
On Tuesday, 28 September 2021 at 13:59:22 UTC, Adam D Ruppe wrote:On Tuesday, 28 September 2021 at 13:51:55 UTC, bauss wrote:Yeah but the point in this case is to get "a" as a string. That's what I meant in my original comment and that's also what's being discussed with nameof.__traits(identifier) doesn't work either. See: https://run.dlang.io/is/9cDdraThat's doing exactly what it is supposed to do. What did you expect and why do you want that?
Sep 28 2021