October 22, 2011
On 2011-10-22 05:36, Robert Jacques wrote:
> On Fri, 21 Oct 2011 17:15:02 -0400, Alex Rønne Petersen
> <xtzgzorex@gmail.com> wrote:
>
>> On 21-10-2011 21:07, Vladimir Panteleev wrote:
>>> Hi,
>>>
>>> Igor Stepanov has created a patch for DMD and Druntime which adds RTTI
>>> information for class and struct members.
>>>
>>> Example:
>>>
>>> import std.stdio;
>>>
>>> class Foo
>>> {
>>> static void PrintHello()
>>> {
>>> writeln("Hello");
>>> }
>>> }
>>> void main()
>>> {
>>> auto info = cast(OffsetTypeInfo_StaticMethod)Foo.classinfo.m_offTi[0];
>>> assert(info.name == "PrintHello");
>>> auto print = cast(void function())info.pointer;
>>> print(); //prints "Hello"
>>> }
>>
>> Absolutely awesome!
>>
>>>
>>> While the inclusion of such functionality into the language remains a
>>> disputed matter, would anyone be interested in an unofficial patch for
>>> this?
>>
>> Yes, very much. I would recommend setting up a fork on GitHub, and then
>> adding it to a branch, e.g. 'reflection', if it's not going to be
>> included in mainline DMD.
>
> Really? A runtime reflection system has been on the review queue for
> over six months and I've brought the subject up on the newsgroup. I've
> received zero feedback. So while I'm sure everyone want to check RTTI
> off the D features list, I've not seen much real interest in it.

I must have completely missed that.

-- 
/Jacob Carlborg
October 22, 2011
On 10/22/11, Vladimir Panteleev <vladimir@thecybershadow.net> wrote:
> On Sat, 22 Oct 2011 13:50:32 +0300, Alex Rønne Petersen <xtzgzorex@gmail.com> wrote:
>
>> You could just introduce a -reflection switch to include reflection information.
>
> As I mentioned in the previous thread on the subject, I think that ideally we should improve compile-time reflection so it's possible to generate runtime reflection information at compilation time. Something like this:
>
> import reflection;
>
> enum reflectionForStdStdio = generateReflectionForModule("std.stdio");
>
> void main()
> {
>      reflectionForStdStdio.callFunction("writeln", "Hello, world!");
> }
>
> --
> Best regards,
>   Vladimir                            mailto:vladimir@thecybershadow.net
>

I think user properties would be a perfect fit for this. :)

@reflected
struct Foo {}
October 22, 2011
On 22-10-2011 15:20, Andrej Mitrovic wrote:
> On 10/22/11, Vladimir Panteleev<vladimir@thecybershadow.net>  wrote:
>> On Sat, 22 Oct 2011 13:50:32 +0300, Alex Rønne Petersen
>> <xtzgzorex@gmail.com>  wrote:
>>
>>> You could just introduce a -reflection switch to include reflection
>>> information.
>>
>> As I mentioned in the previous thread on the subject, I think that ideally
>> we should improve compile-time reflection so it's possible to generate
>> runtime reflection information at compilation time. Something like this:
>>
>> import reflection;
>>
>> enum reflectionForStdStdio = generateReflectionForModule("std.stdio");
>>
>> void main()
>> {
>>       reflectionForStdStdio.callFunction("writeln", "Hello, world!");
>> }
>>
>> --
>> Best regards,
>>    Vladimir                            mailto:vladimir@thecybershadow.net
>>
>
> I think user properties would be a perfect fit for this. :)
>
> @reflected
> struct Foo {}

The only downside with either approach is that people need to explicitly mark their types as "reflectable", which can be a slight hindrance in the way of discoverability (and probably also complicates actual reflection - what if you try to get the return type of a reflected method and that type is not available? This would make for an *awful* lot of null checks).

In any case, if we need to mark stuff as reflectable in-source, I'd vouch for @reflected, though I would really prefer application-global reflection info.

- Alex
October 22, 2011
On Sat, 22 Oct 2011 16:35:57 +0300, Alex Rønne Petersen <xtzgzorex@gmail.com> wrote:

> On 22-10-2011 15:20, Andrej Mitrovic wrote:
>> On 10/22/11, Vladimir Panteleev<vladimir@thecybershadow.net>  wrote:
>>> On Sat, 22 Oct 2011 13:50:32 +0300, Alex Rønne Petersen
>>> <xtzgzorex@gmail.com>  wrote:
>>>
>>>> You could just introduce a -reflection switch to include reflection
>>>> information.
>>>
>>> As I mentioned in the previous thread on the subject, I think that ideally
>>> we should improve compile-time reflection so it's possible to generate
>>> runtime reflection information at compilation time. Something like this:
>>>
>>> import reflection;
>>>
>>> enum reflectionForStdStdio = generateReflectionForModule("std.stdio");
>>>
>>> void main()
>>> {
>>>       reflectionForStdStdio.callFunction("writeln", "Hello, world!");
>>> }
>>>
>>> --
>>> Best regards,
>>>    Vladimir                            mailto:vladimir@thecybershadow.net
>>>
>>
>> I think user properties would be a perfect fit for this. :)
>>
>> @reflected
>> struct Foo {}
>
> The only downside with either approach

What do you mean by "either approach"? Which is the other one?

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
October 22, 2011
On Sat, 22 Oct 2011 07:57:17 -0400, Daniel Gibson <metalcaedes@gmail.com> wrote:
> Am 22.10.2011 05:48, schrieb Robert Jacques:
[snip]
>> What do you mean by their 'parameters'? What about overloads?
>> Attributes? Arguments? Argument attributes?
>>
>
> Primarily arguments. That should help identifying overloads.
> But attributes and argument attributes are needed as well.

But handling overloads is the responsibility of the dispatch system. What would be the use cases for this information?

>>> Something that is close to what Java offers would be great.
>>
>> And what, exactly does JAVA offer? What works? What doesn't work? What's
>> missing?
>
> See
> http://download.oracle.com/javase/6/docs/api/java/lang/Class.html
> You can access constructors (look for one by it's parameters or get all
> of them), the same for methods (methods the class declares and all
> methods, i.e. also inherited ones), implemented interfaces, fields, ...

Thanks, I'll have a look see.

>>> BTW: I don't really see the problem with providing this information
>>> (overhead-wise) - the information needs to be available once per
>>> class/struct, but objects of classes just need one pointer to it (other
>>> types don't even need that because they're not polymorphic and - like
>>> methods of structs - the address of the information is known at
>>> compile-time).
>>
>> 1) Unused information is simply bloat: it increases exe size, slows the
>> exe down and increases the runtime memory footprint.
>
> Yeah, but (mostly) only per class, not per object (besides one pointer
> per object, which shouldn't be that bad and something like this seems is
> already there for the existing typeinfo)

I was assuming the per object bloat was zero. Oh, and I did forget that RTTI increases compile times.
October 22, 2011
Robert Jacques Wrote:

> On Sat, 22 Oct 2011 07:57:17 -0400, Daniel Gibson <metalcaedes@gmail.com> wrote:
> > Am 22.10.2011 05:48, schrieb Robert Jacques:
> [snip]
> >> What do you mean by their 'parameters'? What about overloads? Attributes? Arguments? Argument attributes?
> >>
> >
> > Primarily arguments. That should help identifying overloads. But attributes and argument attributes are needed as well.
> 
> But handling overloads is the responsibility of the dispatch system. What would be the use cases for this information?
> 
> >>> Something that is close to what Java offers would be great.
> >>
> >> And what, exactly does JAVA offer? What works? What doesn't work? What's missing?
> >
> > See
> > http://download.oracle.com/javase/6/docs/api/java/lang/Class.html
> > You can access constructors (look for one by it's parameters or get all
> > of them), the same for methods (methods the class declares and all
> > methods, i.e. also inherited ones), implemented interfaces, fields, ...
> 
> Thanks, I'll have a look see.
> 
> >>> BTW: I don't really see the problem with providing this information (overhead-wise) - the information needs to be available once per class/struct, but objects of classes just need one pointer to it (other types don't even need that because they're not polymorphic and - like methods of structs - the address of the information is known at compile-time).
> >>
> >> 1) Unused information is simply bloat: it increases exe size, slows the exe down and increases the runtime memory footprint.
> >
> > Yeah, but (mostly) only per class, not per object (besides one pointer
> > per object, which shouldn't be that bad and something like this seems is
> > already there for the existing typeinfo)
> 
> I was assuming the per object bloat was zero. Oh, and I did forget that RTTI increases compile times.

IMHO, RTTI should be a built-in feature of the language.
1) You need one global system agreed upon by all clients. Otherwise, you could end up in a situation where a single class has more than a single set of metadata used in several different scenarios.
2) This information is required anyway in the run-time itself. This is a requirement for an accurate GC.
3) Other tools might use this info as well, debuggers, IDEs, etc.
4) It's with the spirit of D design - make the common/safe case the default.

As others mentioned, there should be a compiler switch to turn this off. E.g. when developing for an embedded system where memory is scarce it makes sense to not generate RTTI. It also makes sense to disable the GC and preallocate the memory.
October 22, 2011
On Sat, 22 Oct 2011 06:51:00 -0400, Alex Rønne Petersen <xtzgzorex@gmail.com> wrote:
> On 22-10-2011 05:36, Robert Jacques wrote:
>> On Fri, 21 Oct 2011 17:15:02 -0400, Alex Rønne Petersen
>> <xtzgzorex@gmail.com> wrote:
>>
>>> On 21-10-2011 21:07, Vladimir Panteleev wrote:
>>>> Hi,
>>>>
>>>> Igor Stepanov has created a patch for DMD and Druntime which adds RTTI
>>>> information for class and struct members.
>>>>
>>>> Example:
>>>>
>>>> import std.stdio;
>>>>
>>>> class Foo
>>>> {
>>>> static void PrintHello()
>>>> {
>>>> writeln("Hello");
>>>> }
>>>> }
>>>> void main()
>>>> {
>>>> auto info = cast(OffsetTypeInfo_StaticMethod)Foo.classinfo.m_offTi[0];
>>>> assert(info.name == "PrintHello");
>>>> auto print = cast(void function())info.pointer;
>>>> print(); //prints "Hello"
>>>> }
>>>
>>> Absolutely awesome!
>>>
>>>>
>>>> While the inclusion of such functionality into the language remains a
>>>> disputed matter, would anyone be interested in an unofficial patch for
>>>> this?
>>>
>>> Yes, very much. I would recommend setting up a fork on GitHub, and then
>>> adding it to a branch, e.g. 'reflection', if it's not going to be
>>> included in mainline DMD.
>>
>> Really? A runtime reflection system has been on the review queue for
>> over six months and I've brought the subject up on the newsgroup. I've
>> received zero feedback. So while I'm sure everyone want to check RTTI
>> off the D features list, I've not seen much real interest in it.
>
> I must have missed that. What should I search for to find your thread?

Don't bother; As I said, the thread went nowhere. However, if you'd like to look at the code / docs for my proposed improved variant module:

https://jshare.johnshopkins.edu/rjacque2/public_html/variant.mht
https://jshare.johnshopkins.edu/rjacque2/public_html/variant.d
October 22, 2011
On Sat, 22 Oct 2011 14:38:22 -0400, foobar <foo@bar.com> wrote:
[snip]
> IMHO, RTTI should be a built-in feature of the language.
> 1) You need one global system agreed upon by all clients. Otherwise, you could end up in a situation where a single class has more than a single set of metadata used in several different scenarios.

Or a singleton class/struct. Yes, you should have a single global system, but nothing says that the system has to be the language. Library solution are also valid.

> 2) This information is required anyway in the run-time itself. This is a requirement for an accurate GC.

a) Not every user of D wants to use a GC. In fact, there's currently a push to remove / improve all the GC mandatory features of D to support ref-counting / manual memory usage.
b) RTTI is separate for GC BlockInfo. Yes, you could generate the  GC_BlockInfo from the RTTI, but doing so would be so inefficient that its not worth contemplating.

> 3) Other tools might use this info as well, debuggers, IDEs, etc.

Debuggers and IDEs already have all this information, and a lot more.

> 4) It's with the spirit of D design - make the common/safe case the default.

Since when has reflection ever been the common/safe case? .tupleof, despite being a god-send, is one of the most unsafe features of D. My personal impression of reflection is that it's one of those features that you only want 1% of the time, but if you don't have it, you're going to be pulling teeth to work around it.

> As others mentioned, there should be a compiler switch to turn this off.
> E.g. when developing for an embedded system where memory is scarce it makes sense to not generate RTTI. It also makes sense to disable the GC and preallocate the memory.

Isn't this statement and statement 4) in conflict with each other? Unlike a GC, turning off RTTI breaks everything that uses it.
October 22, 2011
Robert Jacques Wrote:

> On Sat, 22 Oct 2011 14:38:22 -0400, foobar <foo@bar.com> wrote: [snip]
> > IMHO, RTTI should be a built-in feature of the language.
> > 1) You need one global system agreed upon by all clients. Otherwise, you could end up in a situation where a single class has more than a single set of metadata used in several different scenarios.
> 
> Or a singleton class/struct. Yes, you should have a single global system, but nothing says that the system has to be the language. Library solution are also valid.

But couldn't someone implement a different singleton class? How would you make sure the system remains global?

> 
> > 2) This information is required anyway in the run-time itself. This is a requirement for an accurate GC.
> 
> a) Not every user of D wants to use a GC. In fact, there's currently a push to remove / improve all the GC mandatory features of D to support ref-counting / manual memory usage.

Agreed and it is or should be made possible to not use the GC. However the default for D is GC.

> b) RTTI is separate for GC BlockInfo. Yes, you could generate the  GC_BlockInfo from the RTTI, but doing so would be so inefficient that its not worth contemplating.

I'm not sure I follow. Are you discussing D's current GC implementation?
Generally speaking, an accurate GC AFAIK needs to have full type info. D's current GC does not have full type info and can have false positives hence it's a conservative GC.

> 
> > 3) Other tools might use this info as well, debuggers, IDEs, etc.
> 
> Debuggers and IDEs already have all this information, and a lot more.
> 
> > 4) It's with the spirit of D design - make the common/safe case the default.
> 
> Since when has reflection ever been the common/safe case? .tupleof, despite being a god-send, is one of the most unsafe features of D. My personal impression of reflection is that it's one of those features that you only want 1% of the time, but if you don't have it, you're going to be pulling teeth to work around it.

That's why it should be able to turn off RTTI generation if it is not needed but it should be provided by default in order to prevent that pulling teeth sensation. It's safer to provide an off switch rather than an on switch.

> 
> > As others mentioned, there should be a compiler switch to turn this off.
> > E.g. when developing for an embedded system where memory is scarce it makes sense to not generate RTTI. It also makes sense to disable the GC and preallocate the memory.
> 
> Isn't this statement and statement 4) in conflict with each other? Unlike a GC, turning off RTTI breaks everything that uses it.

where's the conflict? If my application does not use RTTI at all than the 'redundant' info can be removed. In fact, Thinking about it just know, It should be a link-time optimization - only if the linker did not see any usage of RTTI in the program, it'll remove the generated meta data.

October 22, 2011
On 22-10-2011 17:18, Vladimir Panteleev wrote:
> On Sat, 22 Oct 2011 16:35:57 +0300, Alex Rønne Petersen
> <xtzgzorex@gmail.com> wrote:
>
>> On 22-10-2011 15:20, Andrej Mitrovic wrote:
>>> On 10/22/11, Vladimir Panteleev<vladimir@thecybershadow.net> wrote:
>>>> On Sat, 22 Oct 2011 13:50:32 +0300, Alex Rønne Petersen
>>>> <xtzgzorex@gmail.com> wrote:
>>>>
>>>>> You could just introduce a -reflection switch to include reflection
>>>>> information.
>>>>
>>>> As I mentioned in the previous thread on the subject, I think that
>>>> ideally
>>>> we should improve compile-time reflection so it's possible to generate
>>>> runtime reflection information at compilation time. Something like
>>>> this:
>>>>
>>>> import reflection;
>>>>
>>>> enum reflectionForStdStdio = generateReflectionForModule("std.stdio");
>>>>
>>>> void main()
>>>> {
>>>> reflectionForStdStdio.callFunction("writeln", "Hello, world!");
>>>> }
>>>>
>>>> --
>>>> Best regards,
>>>> Vladimir mailto:vladimir@thecybershadow.net
>>>>
>>>
>>> I think user properties would be a perfect fit for this. :)
>>>
>>> @reflected
>>> struct Foo {}
>>
>> The only downside with either approach
>
> What do you mean by "either approach"? Which is the other one?
>

@reflected and generateReflectionForModule.

- Alex