April 17, 2012
On 4/16/12 1:02 PM, Sean Kelly wrote:
> As for pointer maps, I think it's reasonable to establish a format
> that these will be made available to the GC, and for them to come
> from elsewhere in the runtime.  I realize that different GC
> implementations may prefer different formats, but hopefully we can
> settle on one that's pretty generally usable and efficient.  I'd
> really rather avoid expecting GC writers to know how to meta-process
> D types to statically generate this themselves.  Moving this into the
> GC would also eliminate the possibility of having the GC chosen at
> link-time, which is something that's currently still an option.

I know you didn't mean it that way, but this gets close enough to a dogma to warrant a protest. "We don't need no steenkin' templates in <sacred area X>" is, I think, an attitude we need to just rid ourselves of. There's the same harm in using templates too much or too little.

The scheme Walter proposed has a lot of flexibility - it plants one pointer to function per type. This is very flexible because that pointer could point to the same function and use a bitmap-based scheme, or (as Walter proposed) point to different instances of a template that does scanning in a type-specific manner.


Andrei
April 17, 2012
On 4/16/12 3:49 PM, Walter Bright wrote:
> Either the compiler has to generate the marking stuff, meaning that no
> user designed GC is very practical, or it has to be generated at compile
> time with a template, where a user designed GC can experiment with a
> much wider range of possibilities without needing compiler modifications.
>
> Also, budding GC implementers will have an existing meta-processing code
> example which will go a long way towards helping get up to speed.
>
> Building a GC is a fairly advanced programming project. I don't think
> it's unreasonable to expect them to be pretty familiar with how D works.

Zat's da spirit!

Andrei

April 17, 2012
On 4/16/2012 7:20 PM, Andrei Alexandrescu wrote:
> The scheme Walter proposed has a lot of flexibility - it plants one pointer to
> function per type. This is very flexible because that pointer could point to the
> same function and use a bitmap-based scheme, or (as Walter proposed) point to
> different instances of a template that does scanning in a type-specific manner.


It could also be a pointer to data. It's entirely up to the template what it's a pointer to.
April 17, 2012
On Monday, 16 April 2012 at 16:53:53 UTC, Walter Bright wrote:
> On 4/16/2012 9:40 AM, Jacob Carlborg wrote:
>> Regardless of how the runtime reflection is generated, by a library or the
>> compiler, it needs to be available to all types.
>
> Why?
>
> (I can see the point for a dynamic language, but not a static one.)

Because you can't take into consideration every possible use for your code. You have to be liberal, because even ONE class forgetting to enable reflection will completely break someone's entire system. For example, you can't serialize just because ONE random collection forgot to enable reflection. As it is right now, the vast majority of the standard library would have to have reflection enabled because the use case is unknown. This is how it would be for most libraries as well. You don't know where your code will be used when writing a library, so you have to play it safe. Opt out is MUCH better than opt in. People who want reflection understand the costs associated with it. People who want reflection build programs where these costs are acceptable.
April 17, 2012
Because you cannot control third party code.

Maybe I am mistaken and with std.variant together with compile-time reflection,
it is possible to cover most use cases that make sense, but I am not 100% sure of it.

--
Paulo

"Walter Bright"  wrote in message news:jmhir1$16nn$1@digitalmars.com...

On 4/16/2012 9:40 AM, Jacob Carlborg wrote:
> Regardless of how the runtime reflection is generated, by a library or the
> compiler, it needs to be available to all types.

Why?

(I can see the point for a dynamic language, but not a static one.) 

April 17, 2012
On Tuesday, 17 April 2012 at 05:34:17 UTC, Kapps wrote:
> On Monday, 16 April 2012 at 16:53:53 UTC, Walter Bright wrote:
>> On 4/16/2012 9:40 AM, Jacob Carlborg wrote:
>>> Regardless of how the runtime reflection is generated, by a library or the
>>> compiler, it needs to be available to all types.
>>
>> Why?
>>
>> (I can see the point for a dynamic language, but not a static one.)
>
> Because you can't take into consideration every possible use for your code. You have to be liberal, because even ONE class forgetting to enable reflection will completely break someone's entire system. For example, you can't serialize just because ONE random collection forgot to enable reflection. As it is right now, the vast majority of the standard library would have to have reflection enabled because the use case is unknown. This is how it would be for most libraries as well. You don't know where your code will be used when writing a library, so you have to play it safe. Opt out is MUCH better than opt in. People who want reflection understand the costs associated with it. People who want reflection build programs where these costs are acceptable.

That's going WAY overboard. An argument can be made about subclass discovery, but it's pretty darn easy to make every aggregated type of a given reflected class be opted-in automatically and recursively.

April 17, 2012
On 2012-04-16 22:42, Timon Gehr wrote:

> This could be fixed by introducing a simple language feature that allows
> a supertype to specify mixin templates that are 'inherited' by all
> subtypes.
>
> Eg:
>
> interface ISerializable {
> ubyte[] serialize();
>
> super mixin Serialize;
> }

Then it won't be possible to serialize third party types if they don't implements ISerializable. In this case, this solution is no better then manually registering types. Actually it's worse, since I can manually register third party types.

-- 
/Jacob Carlborg
April 17, 2012
On 2012-04-16 22:51, Walter Bright wrote:

> Serialization does NOT need to deal with all types, only the types that
> are to be serialized.

Again, if a third party forgets to mark a type for serialization, or runtime reflection I'm out of luck. In in that case what I already have works better.

-- 
/Jacob Carlborg
April 17, 2012
On 2012-04-16 22:52, Steven Schveighoffer wrote:

> I feel this actually can be more generic. Can we change this to a more
> generic term? For example getRTInfo (short for get runtime info) and
> RTInfo(T)?
>
> Here is my thought: the GC is not the only entity that might be
> interested in permanently storing compile-time info for use at runtime.
> Yes, the GC could use this (perhaps exclusively), but this actually
> works as a fairly good hook to generate RTTI necessary to do reflection.
>
> Previously, one had to either parse the object file or make multiple
> passes through the compiler to generate the info and then include it.
> With this template solution, the compiler generates the info using the
> template and then stores it in TypeInfo.
>
> But we need to change the name early on to avoid conflicts. I don't
> think a more generic name would be inappropriate, even if the GC is the
> only client at first.
>
> -Steve

If we get custom attributes perhaps this case be used to store them. BTW, why not make it a property and drop the "get" prefix.

-- 
/Jacob Carlborg
April 17, 2012
On 4/16/2012 11:26 PM, Jacob Carlborg wrote:
> Then it won't be possible to serialize third party types if they don't
> implements ISerializable. In this case, this solution is no better then manually
> registering types. Actually it's worse, since I can manually register third
> party types.

I'm not so sure in D that you can serialize arbitrary types without them designed to be serializable. For example, what will you do with unions? Pointers to global data?