digitalmars.D - Getting derived classes
- dsimcha <dsimcha yahoo.com> Oct 16 2008
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Oct 16 2008
- dsimcha <dsimcha yahoo.com> Oct 16 2008
- Jason House <jason.james.house gmail.com> Oct 16 2008
- Sean Kelly <sean invisibleduck.org> Oct 16 2008
- Jason House <jason.james.house gmail.com> Oct 17 2008
- "Denis Koroskin" <2korden gmail.com> Oct 16 2008
- Ary Borenszweig <ary esperanto.org.ar> Oct 17 2008
- "Steven Schveighoffer" <schveiguy yahoo.com> Oct 17 2008
- Ary Borenszweig <ary esperanto.org.ar> Oct 17 2008
- "Steven Schveighoffer" <schveiguy yahoo.com> Oct 17 2008
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Oct 17 2008
- Sean Kelly <sean invisibleduck.org> Oct 17 2008
- "Steven Schveighoffer" <schveiguy yahoo.com> Oct 17 2008
- Christopher Wright <dhasenan gmail.com> Nov 01 2008
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Oct 21 2008
- Robert Fraser <fraserofthenight gmail.com> Oct 21 2008
- BLS <nanali nospam-wanadoo.fr> Nov 01 2008
- BCS <ao pathlink.com> Oct 17 2008
- Don <nospam nospam.com.au> Oct 20 2008
- "Bill Baxter" <wbaxter gmail.com> Oct 17 2008
- BCS <ao pathlink.com> Oct 17 2008
- "Jarrett Billingsley" <jarrett.billingsley gmail.com> Oct 17 2008
I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
Oct 16 2008
dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
That's not possible in general because in D the derived classes form an open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time. Andrei
Oct 16 2008
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articledsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time. Andrei
Not quite sure I understand why this has to be the case. Somewhere in the docs, Walter explicitly says that, since D knows about the whole class tree, the compiler can figure out which functions in a hierarchy can be made non-virtual. If this is the case, why is the compiler not able to know about the whole class tree for purposes of creating lists of derived classes?
Oct 16 2008
dsimcha wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articledsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time. Andrei
Not quite sure I understand why this has to be the case. Somewhere in the docs, Walter explicitly says that, since D knows about the whole class tree, the compiler can figure out which functions in a hierarchy can be made non-virtual. If this is the case, why is the compiler not able to know about the whole class tree for purposes of creating lists of derived classes?
There are many things hiding somewhere in the docs are many things that are not implemented :)
Oct 16 2008
dsimcha wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articledsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time. Andrei
Not quite sure I understand why this has to be the case. Somewhere in the docs, Walter explicitly says that, since D knows about the whole class tree, the compiler can figure out which functions in a hierarchy can be made non-virtual. If this is the case, why is the compiler not able to know about the whole class tree for purposes of creating lists of derived classes?
I think the actual implementation of this is somewhat different. Rather than relying on knowledge of the entire class tree, the compiler simply has to know what type a particular function is being called on. For example: class C { void fn() {} } void main() { auto c = new C; c.fn(); } Here, the compiler knows that it's dealing with an instance of C rather than a possibly unknown derived class so it can call fn() directly rather than going through the vtbl. However: void callFn( C c ) { c.fn(); } Here, the compiler doesn't know what the underlying type is so it must go through the vtbl. Sean
Oct 16 2008
Sean Kelly Wrote:dsimcha wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articledsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time. Andrei
Not quite sure I understand why this has to be the case. Somewhere in the docs, Walter explicitly says that, since D knows about the whole class tree, the compiler can figure out which functions in a hierarchy can be made non-virtual. If this is the case, why is the compiler not able to know about the whole class tree for purposes of creating lists of derived classes?
I think the actual implementation of this is somewhat different. Rather than relying on knowledge of the entire class tree, the compiler simply has to know what type a particular function is being called on. For example: class C { void fn() {} } void main() { auto c = new C; c.fn(); } Here, the compiler knows that it's dealing with an instance of C rather than a possibly unknown derived class so it can call fn() directly rather than going through the vtbl. However: void callFn( C c ) { c.fn(); } Here, the compiler doesn't know what the underlying type is so it must go through the vtbl. Sean
The compiler could be smarter than that, but isn't. I too was tricked by the same bit of D documentation. Avoiding virtual calls can be a significant speed gain. I have final functions throughout my code because gdc was too stupid to recognize they could be.
Oct 17 2008
dsimcha <dsimcha yahoo.com> писал(а) в своём письме Fri, 17 Oct 2008 06:18:34 +0400:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articledsimcha wrote:I know that, in std.traits, there's a template that spits out all
for a given class. Based on reading the source, it seems to work
rather interesting use case for is expressions. Is there any
to do the opposite: For any given position in a class hierarchy, to
tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time. Andrei
Not quite sure I understand why this has to be the case. Somewhere in the docs, Walter explicitly says that, since D knows about the whole class tree, the compiler can figure out which functions in a hierarchy can be made non-virtual. If this is the case, why is the compiler not able to know about the whole class tree for purposes of creating lists of derived classes?
How do you get a list of all classes that derive from Object? I might write one, too! Imagine we compile the source separately and then link obj files together.
Oct 16 2008
Andrei Alexandrescu escribió:dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
That's not possible in general because in D the derived classes form an open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time.
But for a given set of modules, the hierarchy is finite and known.Andrei
Oct 17 2008
"Ary Borenszweig" wroteAndrei Alexandrescu escribi:dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
That's not possible in general because in D the derived classes form an open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time.
But for a given set of modules, the hierarchy is finite and known.
Not at compile time, only at link time. You can't compile code at link time. -Steve
Oct 17 2008
Steven Schveighoffer wrote:"Ary Borenszweig" wroteAndrei Alexandrescu escribi:dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time.
Not at compile time, only at link time. You can't compile code at link time.
I still don't understand why you can't do this at compile time, assuming you have the source code for everything that you'll link into your executable. How is a class hierarchy different in D than in Java? Eclipse JDT's has a type hierarchy feature, and Bruno was going to implement it in Mrnmhrm, all based on what's defined in the modules (you can say, compilte-time). What's the problem?-Steve
Oct 17 2008
"Ary Borenszweig" wroteSteven Schveighoffer wrote:"Ary Borenszweig" wroteAndrei Alexandrescu escribi:dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time.
Not at compile time, only at link time. You can't compile code at link time.
I still don't understand why you can't do this at compile time, assuming you have the source code for everything that you'll link into your executable.
Let's say this feature theoretically existed. Here's an example usage: class X { Tuple!(???) getAllDerivedTypes() { return std.getAllDerivedTypes!(X)();} } If you compile this module like: dmd -c X.d; At this point, how does the compiler know all the modules that will derive from X? D's compile-time reflection is generally limited to what is at or below a certain point in the hierarchy, not what has derived from it. If you wanted to do something at runtime, that is possible, you might even be able to do this today by looking at the global TypeInfo array. But you certainly cannot get a tuple of the derived classes at compile-time.How is a class hierarchy different in D than in Java? Eclipse JDT's has a type hierarchy feature, and Bruno was going to implement it in Mrnmhrm, all based on what's defined in the modules (you can say, compilte-time). What's the problem?
Java has runtime reflection. D does not. You have to implement runtime reflection on top of compile time reflection (or so says Walter). There should be no problem if you want the information at runtime. But a Tuple is a compile-time entity. You can probably get the TypeInfos of the classes, but not really be able to do much, since D's runtime reflection capabilities are limited. -Steve
Oct 17 2008
Steven Schveighoffer wrote:"Ary Borenszweig" wroteSteven Schveighoffer wrote:"Ary Borenszweig" wroteAndrei Alexandrescu escribi:dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time.
time.
you have the source code for everything that you'll link into your executable.
Let's say this feature theoretically existed. Here's an example usage: class X { Tuple!(???) getAllDerivedTypes() { return std.getAllDerivedTypes!(X)();} } If you compile this module like: dmd -c X.d; At this point, how does the compiler know all the modules that will derive from X?
Well explained.D's compile-time reflection is generally limited to what is at or below a certain point in the hierarchy, not what has derived from it.
s/below/above/If you wanted to do something at runtime, that is possible, you might even be able to do this today by looking at the global TypeInfo array. But you certainly cannot get a tuple of the derived classes at compile-time.How is a class hierarchy different in D than in Java? Eclipse JDT's has a type hierarchy feature, and Bruno was going to implement it in Mrnmhrm, all based on what's defined in the modules (you can say, compilte-time). What's the problem?
Java has runtime reflection. D does not. You have to implement runtime reflection on top of compile time reflection (or so says Walter).
I said so. All derived classes is, however, a case of runtime-available information that's not there during compilation. Anyhow, there's a start with the function static Object.factory(string). You give it a string, it gives you a newly-instanced object. So the information is there, it just needs exposing. Andrei
Oct 17 2008
Andrei Alexandrescu wrote:Anyhow, there's a start with the function static Object.factory(string). You give it a string, it gives you a newly-instanced object. So the information is there, it just needs exposing.
Much of it is even exposed, just not in a convenient manner. A list of classes is available via ModuleInfo, and ClassInfo provides a means of finding the ClassInfo instance of a class by name. From there it should be possible to obtain a list of parent classes, and so one could build a hierarchy graph with some work. Sean
Oct 17 2008
"Sean Kelly" wroteAndrei Alexandrescu wrote:Anyhow, there's a start with the function static Object.factory(string). You give it a string, it gives you a newly-instanced object. So the information is there, it just needs exposing.
Much of it is even exposed, just not in a convenient manner. A list of classes is available via ModuleInfo, and ClassInfo provides a means of finding the ClassInfo instance of a class by name. From there it should be possible to obtain a list of parent classes, and so one could build a hierarchy graph with some work.
Sure, but what do you do with that graph ;) Calling methods/ctors is not exactly easy with D currently. -Steve
Oct 17 2008
Steven Schveighoffer wrote:"Sean Kelly" wroteAndrei Alexandrescu wrote:Anyhow, there's a start with the function static Object.factory(string). You give it a string, it gives you a newly-instanced object. So the information is there, it just needs exposing.
classes is available via ModuleInfo, and ClassInfo provides a means of finding the ClassInfo instance of a class by name. From there it should be possible to obtain a list of parent classes, and so one could build a hierarchy graph with some work.
Sure, but what do you do with that graph ;) Calling methods/ctors is not exactly easy with D currently. -Steve
Parameterless constructors are easy. Other than that, you can't be certain what expectations the constructor has, so it's a bit dangerous, but you can of course get around that with documentation and try/catch. Calling methods isn't so difficult, either, since most of the stuff you'll be able to do involves virtual methods from some known base class. Dunit uses runtime reflection to get all test fixtures and run them. It uses something like: ClassInfo[] derived(ClassInfo info) { ClassInfo[] derivedClasses; foreach (module; ModuleInfo) foreach (clazz; module.localClasses) { if (isDerived(clazz; info)) derivedClasses ~= clazz; } return derivedClasses; } // Only works for interfaces. bool isDerived(ClassInfo derived, ClassInfo base) { while (derived) { if (base is derived) return true; derived = derived.base; } } I did this because I was tired of the static ctor mixin / static singleton registration pattern. I used to have to do: class FooTests : TestFixture { // I already told you it's a test fixture! // You mean I have to tell you twice?! mixin (DunitTest); } Now I can skip the mixin.
Nov 01 2008
Ary Borenszweig wrote:Steven Schveighoffer wrote:"Ary Borenszweig" wroteAndrei Alexandrescu escribi:dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
an open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time.
Not at compile time, only at link time. You can't compile code at link time.
I still don't understand why you can't do this at compile time, assuming you have the source code for everything that you'll link into your executable. How is a class hierarchy different in D than in Java? Eclipse JDT's has a type hierarchy feature, and Bruno was going to implement it in Mrnmhrm, all based on what's defined in the modules (you can say, compilte-time). What's the problem?
It would be possible for the compiler to determine subtypes, if, just like an IDE or build tool, the compiler had a well structured concept of a project (ie, a set of source folders, libraries, included modules, etc.). But just because it is possible, doesn't mean it's desirable, and in fact, it isn't. It's senseless: Such code (ie, getting all derived types) would introduce an open-ended compile-time coupling, as a module using that functionality would depended on *every* other module of the project. And that makes such functionality compilable only in projects that compile into an executable (which is when the set of dependencies is finite). That is, you couldn't use that functionality in a library, which shows much of an inane idea it is. It's breaking an abstraction barrier. Getting that information at *runtime* might be sensible, but I'm not seeing much usefulness in that. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Oct 21 2008
Bruno Medeiros wrote:Getting that information at *runtime* might be sensible, but I'm not seeing much usefulness in that.
The main use case I can see is a plugin solution. For example, automatically instantiate all classes that extend IPlugin or something. However, requiring a config file that includes the class name and maybe some metadata isn't too hard to do and is potentially more efficient.
Oct 21 2008
Andrei Alexandrescu schrieb:dsimcha wrote:I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
That's not possible in general because in D the derived classes form an open set. I guess it could be done at runtime via reflection (not implemented afaik), but not at compile time. Andrei
-> Jacha Wetzel Here is a simple way of adding __traits based runtime reflection to D classes: http://mainia.de/classinfoex.d (requires DMD 2.004)
Nov 01 2008
Reply to dsimcha,I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
Via DLL/SO's, a derived class can be /written/ after the program that it will be used in is /compiled/. Because of that (and other less restrictive forms of that issue) The most general answer is; can't be done.
Oct 17 2008
Jarrett Billingsley wrote:On Fri, Oct 17, 2008 at 5:34 PM, Bill Baxter <wbaxter gmail.com> wrote:I wonder what Object.Factory does when you try to make a class from a DLL like that. I'm guessing it doesn't work.
I think you've guessed correctly. DLLs, in general, are next to useless with D.
Rather: A D app and a D DLL can only communicate via extern(C) interfaces. Or via COM. It's not great, but it isn't any worse than DLLs in C++.
Oct 20 2008
On Sat, Oct 18, 2008 at 6:20 AM, BCS <ao pathlink.com> wrote:Reply to dsimcha,I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
Via DLL/SO's, a derived class can be /written/ after the program that it will be used in is /compiled/. Because of that (and other less restrictive forms of that issue) The most general answer is; can't be done.
I wonder what Object.Factory does when you try to make a class from a DLL like that. I'm guessing it doesn't work. --bb
Oct 17 2008
Reply to Bill,On Sat, Oct 18, 2008 at 6:20 AM, BCS <ao pathlink.com> wrote:Reply to dsimcha,I know that, in std.traits, there's a template that spits out all base classes for a given class. Based on reading the source, it seems to work based on a rather interesting use case for is expressions. Is there any equivalent way to do the opposite: For any given position in a class hierarchy, to get a tuple of all possible descendants?
it will be used in is /compiled/. Because of that (and other less restrictive forms of that issue) The most general answer is; can't be done.
DLL like that. I'm guessing it doesn't work. --bb
it might work by hiding a static this function that registries the class, from that, when the dll lodes the class is registered.
Oct 17 2008
On Fri, Oct 17, 2008 at 5:34 PM, Bill Baxter <wbaxter gmail.com> wrote:I wonder what Object.Factory does when you try to make a class from a DLL like that. I'm guessing it doesn't work.
I think you've guessed correctly. DLLs, in general, are next to useless with D.
Oct 17 2008









Jason House <jason.james.house gmail.com> 