April 17, 2012
Le 17/04/2012 11:42, Walter Bright a écrit :
> On 4/17/2012 1:47 AM, deadalnix wrote:
>> Le 17/04/2012 05:22, Walter Bright a écrit :
>>> 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.
>>
>> Data can eventually be stored IN the pointer if needed. Does the
>> system allow
>> that ? If it doesn't, is it possible to enable it ?
>
> I don't know what you mean.

If the data fit into the pointer (ie 32bits or 64bits), you don't need to point to data. You can just decide that the pointer IS the data. In other terms :

void* ptr;
size_t data = cast(size_t) ptr;

Such a size if sufficient for many types.
April 17, 2012
On 17-04-2012 10:13, Walter Bright wrote:
> On 4/17/2012 1:10 AM, Walter Bright wrote:
>> On 4/16/2012 11:50 PM, Jacob Carlborg wrote:
>>> On 2012-04-17 08:33, Walter Bright wrote:
>>>> 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?
>>>
>>> Not all types are serializable of course.
>>
>> How would you know if they are or aren't, when dynamically loading stuff?
>
> Essentially, I'm concerned with a vast amount of data being generated
> for every type and inserted into the executables (which are already
> large). Even worse, I'm concerned that such a feature will not "just
> work" when one wants to serialize a class that wasn't designed to be
> serialized, and it'll come off as a crappy half-assed buggy misfeature.

Would turning on global reflection data generation with a compiler switch be reasonable? Then when libraries query for reflection information, they just have to check whether it's actually there (and if not, most likely error).

Anyway, I don't think reflection has the potential to be a misfeature; that's stretching it. Redundancy can certainly be incurred, but with a switch to enable reflection, it would only happen when the user actually wants it to.

As for the just works factor - if the serialization library is designed well enough (which I'm confident Jacob's library either is can be made to be), it isn't really a problem. Serializing a graph of objects is pretty standard (see e.g. .NET binary serialization).

Even better, the library could just error out (instead of producing garbage) when it discovers that it can't serialize a type in any sensible fashion.

-- 
- Alex
April 17, 2012
Le 17/04/2012 14:31, Alex Rønne Petersen a écrit :
> On 17-04-2012 10:13, Walter Bright wrote:
>> On 4/17/2012 1:10 AM, Walter Bright wrote:
>>> On 4/16/2012 11:50 PM, Jacob Carlborg wrote:
>>>> On 2012-04-17 08:33, Walter Bright wrote:
>>>>> 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?
>>>>
>>>> Not all types are serializable of course.
>>>
>>> How would you know if they are or aren't, when dynamically loading
>>> stuff?
>>
>> Essentially, I'm concerned with a vast amount of data being generated
>> for every type and inserted into the executables (which are already
>> large). Even worse, I'm concerned that such a feature will not "just
>> work" when one wants to serialize a class that wasn't designed to be
>> serialized, and it'll come off as a crappy half-assed buggy misfeature.
>
> Would turning on global reflection data generation with a compiler
> switch be reasonable? Then when libraries query for reflection
> information, they just have to check whether it's actually there (and if
> not, most likely error).
>
> Anyway, I don't think reflection has the potential to be a misfeature;
> that's stretching it. Redundancy can certainly be incurred, but with a
> switch to enable reflection, it would only happen when the user actually
> wants it to.
>
> As for the just works factor - if the serialization library is designed
> well enough (which I'm confident Jacob's library either is can be made
> to be), it isn't really a problem. Serializing a graph of objects is
> pretty standard (see e.g. .NET binary serialization).
>
> Even better, the library could just error out (instead of producing
> garbage) when it discovers that it can't serialize a type in any
> sensible fashion.
>

I don't see any need for runtime reflection here.

If a type is serialized, at some point it have to be given to the lib, that can generate runtime information from compile time reflection capability. If the type is never serialized/deserialized, then runtime reflection is useless.
April 17, 2012
On 04/17/2012 04:44 PM, deadalnix wrote:
...
>
> I don't see any need for runtime reflection here.
>
> If a type is serialized, at some point it have to be given to the lib,
> that can generate runtime information from compile time reflection
> capability. If the type is never serialized/deserialized, then runtime
> reflection is useless.

Assigning an object to a base class reference loses the relevant compile time information.

Object o = new A;
auto s = serialize(o); // library cannot know about 'A'
April 17, 2012
On 2012-04-17 16:44, deadalnix wrote:

> I don't see any need for runtime reflection here.
>
> If a type is serialized, at some point it have to be given to the lib

No it doesn't. Not if if you serialize through a base class reference.

class Base { ... }
class Base : Sub { ... }

Base b = new Sub;
serialize(b);

The serializer will never no anything about "Sub". Of course it's possible to register "Sub" with the serializer but that's what I'm trying to avoid in the first place.

-- 
/Jacob Carlborg
April 17, 2012
On 4/17/2012 3:31 AM, deadalnix wrote:
> If the data fit into the pointer (ie 32bits or 64bits), you don't need to point
> to data. You can just decide that the pointer IS the data. In other terms :
>
> void* ptr;
> size_t data = cast(size_t) ptr;
>
> Such a size if sufficient for many types.

Yes, that's true.
April 18, 2012
"Jacob Carlborg" <doob@me.com> wrote in message news:jmjb2v$1d2k$1@digitalmars.com...
>
> What's not possible is when the runtime type is different from the static type:
>
> class Base { ... }
> class Sub : Base { ... }
>
> Base b = new Sub;
>
> In the above code, when inspecting "b" using compile time reflection all information about "Sub" is gone. It's just a regular "Base".
>

Can't you just query compile-time information to see what classes inherit from Base? Then you could just try downcasting to them.


April 18, 2012
On 4/16/2012 1:54 PM, Steven Schveighoffer wrote:
> On Mon, 16 Apr 2012 16:52:54 -0400, Steven Schveighoffer <schveiguy@yahoo.com>
> wrote:
>
>> 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.
>
> Should have said "But we need to change the name early on to avoid confusion
> later", i.e. "why is this GCInfo template generating reflection info that the GC
> doesn't use?"


Not a bad idea.
April 18, 2012
On 18/04/2012 02:11, Nick Sabalausky wrote:
> Can't you just query compile-time information to see what classes inherit
> from Base? Then you could just try downcasting to them.

Last time I checked there was no way to do that (I doubt that will have changed). It's impossible to know all the subclasses until link-time, so you'll get different results depending on how you compile your project. The only way around this that I've found is to put a mixin in all subclasses to register them with the base class... That's a complete hack though.

Example:
----
// a.d
class Base { /* whatever magic to get derived classes */ }
// b.d
import a;
class Derived : Base {}
void main() {}
----
$ dmd -c a.d

dmd does not know about b.d when compiling a.d. The only way this could work is to allow link-time code generation.

-- 
Robert
http://octarineparrot.com/
April 18, 2012
On Wednesday, 18 April 2012 at 10:07:59 UTC, Robert Clipsham wrote:
> // a.d
> class Base { /* whatever magic to get derived classes */ }
> // b.d
> import a;
> class Derived : Base {}
> void main() {}

to find derived classes at runtime:
http://forum.dlang.org/thread/mailman.1052.1292505452.21107.digitalmars-d-learn@puremagic.com#post-op.vns7nfjpvxi10f:40biotronic-pc.lan