View mode: basic / threaded / horizontal-split · Log in · Help
May 18, 2009
The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Re: The Final(ize) Challenge
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
Top | Discussion index | About this forum | D home