May 18, 2009
Ok, now with the advent (or rediscovery) of allMembers which I had no idea existed, we're ready to start some serious butt-kick reflection facilities.

For starters, I'd like to present you with the following challenge. Given any class C, e.g.:

class C
{
    void foo(int) { ... }
    int bar(string) { ... }
}

define a template class Finalize(T) such that Finalize!(C) is the same as the following hand-written class:

final class FinalizeC : C
{
    final void foo(int a) { return super.foo(a); }
    final int bar(string a) { return super.bar(a); }
}

Finalize is cool when you need some functionality from an exact class and you don't want to pay indirect calls throughout. All calls through Finalize!(C)'s methods will resolve to static calls.


Have at it!

Andrei
May 18, 2009
On Mon, May 18, 2009 at 12:12 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Ok, now with the advent (or rediscovery) of allMembers which I had no idea existed, we're ready to start some serious butt-kick reflection facilities.
>
> For starters, I'd like to present you with the following challenge. Given any class C, e.g.:
>
> class C
> {
>    void foo(int) { ... }
>    int bar(string) { ... }
> }
>
> define a template class Finalize(T) such that Finalize!(C) is the same as
> the following hand-written class:
>
> final class FinalizeC : C
> {
>    final void foo(int a) { return super.foo(a); }
>    final int bar(string a) { return super.bar(a); }
> }
>
> Finalize is cool when you need some functionality from an exact class and you don't want to pay indirect calls throughout. All calls through Finalize!(C)'s methods will resolve to static calls.

There are two challenging aspects that I'm running into.

The first is a more general statement about trying to generate functions with D's metaprogramming.  It is a huge pain in the ass to actually create a function with a given name, because the only way that I know this can be done is with a string mixin.  As soon as we venture into that territory, we have to consider things like how to convert a parameter type tuple into a string, and whether or not the .stringof a type will be correctly qualified (I've run into problems with this before, where some code in a library is not able to mix in a string because it doesn't import the same modules that the calling code does, and then you just get undefined identifier errors).  For the love of all that is holy, can we PLEASE get something like __ident("blah")?  This would be so much easier and would probably drastically reduce my use of string mixins in general.

The second is worse.  __ctor (if it exists) is not virtual, so it's not possible to get a list of overloads of it with __traits.  One of two things has to change: either __traits needs a way to get overloads of nonvirtual functions (that seems like an incredible oversight!), or as Sean and others have proposed numerous times, derived classes should inherit ctors.  This would eliminate the need to write forwarding constructors in the Finalize class altogether.
May 18, 2009
Jarrett Billingsley wrote:
> The second is worse.  __ctor (if it exists) is not virtual, so it's
> not possible to get a list of overloads of it with __traits.

This is a simple one:

final class Finalize(C) : C
{
    this(A...)(A args) if (is(new C(args))
    {
        super(args);
    }
}


Andrei
May 18, 2009
On Mon, May 18, 2009 at 1:48 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Jarrett Billingsley wrote:
>>
>> The second is worse.  __ctor (if it exists) is not virtual, so it's not possible to get a list of overloads of it with __traits.
>
> This is a simple one:
>
> final class Finalize(C) : C
> {
>    this(A...)(A args) if (is(new C(args))
>    {
>        super(args);
>    }
> }

What the!
May 18, 2009
Jarrett Billingsley wrote:
> On Mon, May 18, 2009 at 1:48 PM, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>> Jarrett Billingsley wrote:
>>> The second is worse.  __ctor (if it exists) is not virtual, so it's
>>> not possible to get a list of overloads of it with __traits.
>> This is a simple one:
>>
>> final class Finalize(C) : C
>> {
>>    this(A...)(A args) if (is(new C(args))
>>    {
>>        super(args);
>>    }
>> }
> 
> What the!

I know, I didn't close a paren :o).

Andrei
May 18, 2009
Andrei Alexandrescu wrote:
> Jarrett Billingsley wrote:
>> On Mon, May 18, 2009 at 1:48 PM, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org> wrote:
>>> Jarrett Billingsley wrote:
>>>> The second is worse.  __ctor (if it exists) is not virtual, so it's
>>>> not possible to get a list of overloads of it with __traits.
>>> This is a simple one:
>>>
>>> final class Finalize(C) : C
>>> {
>>>    this(A...)(A args) if (is(new C(args))
>>>    {
>>>        super(args);
>>>    }
>>> }
>>
>> What the!
> 
> I know, I didn't close a paren :o).
> 
> Andrei

And I forgot the typeof again :o(. Redux:

final class Finalize(C) : C
{
   this(A...)(A args) if (is(typeof(new C(args))))
   {
       super(args);
   }
}

This won't compile with 2.030 (args is not visible in the if-clause), but it should, and Walter has fixed that in his tree already.

Andrei
May 18, 2009
Andrei Alexandrescu wrote:

> Ok, now with the advent (or rediscovery) of allMembers which I had no idea existed, we're ready to start some serious butt-kick reflection facilities.
> 
> For starters, I'd like to present you with the following challenge.

Unless there's been a change in D2 I have missed, I don't think you can forward functions with ref/out or default arguments correctly unless you parse certain mangles or stringofs.


May 18, 2009
On Mon, May 18, 2009 at 10:53 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Jarrett Billingsley wrote:
>>
>> On Mon, May 18, 2009 at 1:48 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>
>>> Jarrett Billingsley wrote:
>>>>
>>>> The second is worse.  __ctor (if it exists) is not virtual, so it's not possible to get a list of overloads of it with __traits.
>>>
>>> This is a simple one:
>>>
>>> final class Finalize(C) : C
>>> {
>>>   this(A...)(A args) if (is(new C(args))
>>>   {
>>>       super(args);
>>>   }
>>> }
>>
>> What the!
>
> I know, I didn't close a paren :o).

When did templated constructors start being allowed?!  I see nothing about it in the change log.

--bb
May 18, 2009
On Mon, May 18, 2009 at 1:56 PM, Bill Baxter <wbaxter@gmail.com> wrote:
>
> When did templated constructors start being allowed?!  I see nothing about it in the change log.

I was about to say the same thing.
May 18, 2009
On Mon, May 18, 2009 at 1:57 PM, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
> On Mon, May 18, 2009 at 1:56 PM, Bill Baxter <wbaxter@gmail.com> wrote:
>>
>> When did templated constructors start being allowed?!  I see nothing about it in the change log.
>
> I was about to say the same thing.
>

It doesn't work.  Let me guess: 2.031.  :P
« First   ‹ Prev
1 2 3 4 5 6
Top | Discussion index | About this forum | D home