May 18, 2009
On Mon, May 18, 2009 at 12:12 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Have at it!

Well?  Where's my cookie?  ;)
May 18, 2009
Jarrett Billingsley wrote:
> On Mon, May 18, 2009 at 12:12 PM, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
> 
>> Have at it!
> 
> Well?  Where's my cookie?  ;)

As soon as I'm coming off my prostration and awe engendered by your solution, I'll reply to that. I have to admit, though, that Denis' insight sort of took the wind out of my sails.

Thanks!

Andrei
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.  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.

http://d.puremagic.com/issues/show_bug.cgi?id=2855
May 18, 2009
Frits van Bommel wrote:
> Andrei Alexandrescu wrote:
>> Good point! Now define Unfinalize that opens the final methods of a class for method overriding.
>>
>> class A
>> {
>>     final int foo(string) { ... }
>> }
>>
>> class UnfinalizeA : A
>> {
>>     int foo(string a) { return super.foo(a); }
>> }
> 
> DMD rightly doesn't allow this:
> ---
> test.d(8): Error: function test.UnfinalizeA.foo cannot override final function test.A.foo
> ---
> 
> There's a workaround though:
> ---
> class UnfinalizeA : A
> {
>     int foo_(string a) { return super.foo(a); }
>     alias foo_ foo;
> }

Damn. I meant to NOT inherit from A.

Andrei
May 18, 2009
Andrei Alexandrescu wrote:
> I think you need to operate exclusively with string mixins in Finalize, so __ident would be of marginal help there. Also, static foreach is much more necessary.

That is a huge problem.

Let's say that the class you want to finalize, Target, has a method like this:
void foo(SomeClass){}

Let's say that SomeClass is private and in the same module as Target.

You *may* be able to do this with templates. Probably.

You *can never* do this with a string mixin.

Let's say you have another method:
void bar(SomeOtherClass!(int)){}

SomeOtherClass!(int).stringof == "SomeOtherClass". That is also guaranteed fail.


What you can do is:
void foo(ParameterTupleOf!(__traits(getVirtualFunctions, Target, "foo")[0] u) { super.foo(u); }

Here, the only string you need to mix in is for the identifier.
May 18, 2009
On Mon, May 18, 2009 at 6:54 PM, Christopher Wright <dhasenan@gmail.com> wrote:
> Andrei Alexandrescu wrote:
>>
>> I think you need to operate exclusively with string mixins in Finalize, so __ident would be of marginal help there. Also, static foreach is much more necessary.
>
> That is a huge problem.
>
> Let's say that the class you want to finalize, Target, has a method like
> this:
> void foo(SomeClass){}
>
> Let's say that SomeClass is private and in the same module as Target.
>
> You *may* be able to do this with templates. Probably.
>
> You *can never* do this with a string mixin.

Exactly.  This is one of the problems I mentioned earlier, and I know Andrei's got experience with this as well - std.algorithm doesn't import std.math by default, so you can't use math functions in the string expressions.  Oh sure, you could kludge that in there, but it's far from scalable.
May 18, 2009
Christopher Wright wrote:
> Andrei Alexandrescu wrote:
>> I think you need to operate exclusively with string mixins in Finalize, so __ident would be of marginal help there. Also, static foreach is much more necessary.
> 
> That is a huge problem.
> 
> Let's say that the class you want to finalize, Target, has a method like this:
> void foo(SomeClass){}
> 
> Let's say that SomeClass is private and in the same module as Target.
> 
> You *may* be able to do this with templates. Probably.
> 
> You *can never* do this with a string mixin.

Of course you can. All you have to do is first check whether the call is accessible from your instantiation point, BEFORE generating the string.


Andrei
May 19, 2009
Andrei Alexandrescu wrote:
> Christopher Wright wrote:
>> Andrei Alexandrescu wrote:
>>> I think you need to operate exclusively with string mixins in Finalize, so __ident would be of marginal help there. Also, static foreach is much more necessary.
>>
>> That is a huge problem.
>>
>> Let's say that the class you want to finalize, Target, has a method like this:
>> void foo(SomeClass){}
>>
>> Let's say that SomeClass is private and in the same module as Target.
>>
>> You *may* be able to do this with templates. Probably.
>>
>> You *can never* do this with a string mixin.
> 
> Of course you can. All you have to do is first check whether the call is accessible from your instantiation point, BEFORE generating the string.
> 
> 
> Andrei

And a lot of interesting usages will have the Finalize template instantiated far from user code, but then passed back to user code. This means you can't do much at all with string mixins.

I faced that problem with dmocks and didn't find a good solution for it while still working on dmocks.
May 19, 2009

Jarrett Billingsley wrote:
> 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

It's hardly fair to issue a challenge which can only be completed [1] with an unreleased compiler only you have seen.

Actually, that *still* isn't going to cut it: it won't handle ref or out arguments correctly.  I'm not sure what it'd do with scope.

We *really* need to come up with a sane solution to generalising on storage class.  Every time I have to generate functions, they make my life a complete pain in the arse.  The only solution I've found is this hideous hack that parses ParameterTuple!(T).stringof and builds an array of enums... yech.

... and yeah, when were you gonna tell us about templated ctors?!

  -- Daniel


[1] Qualification because I know if I don't, I'll regret it: I'm assuming the next compiler does support templated ctors (as otherwise your "it's easy" statement is bogus) and that this is the only way of solving the problem (I can't think of any other way of doing it.)
May 19, 2009

Ary Borenszweig wrote:
> Jarrett Billingsley wrote:
>> ...  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.
> 
> Better __traits(ident, "blah")?

That'd only make sense if it was interrogative; it's constructive.

  -- Daniel