May 19, 2009
Daniel Keep wrote:
> 
> 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.

I don't have 2.031 and I don't know whether it will fix the template constructor bug.

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

It's much easier to parse ParameterTuple!(T)[n].stringof. If it starts with "ref "/"out " then it's a ref/out.

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

You could for now comment out the constructor and leave it until the bug is fixed.


Andrei
May 20, 2009

Andrei Alexandrescu wrote:
> Daniel Keep wrote:
>> ...
>>
>> It's hardly fair to issue a challenge which can only be completed [1] with an unreleased compiler only you have seen.
> 
> I don't have 2.031 and I don't know whether it will fix the template constructor bug.

Dude, you got my hopes up with that.  :'(

>> 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.
> 
> It's much easier to parse ParameterTuple!(T)[n].stringof. If it starts with "ref "/"out " then it's a ref/out.

These magic tuples have a horrible habit of losing this invisible extra information when you so much as think about them.  I didn't realise you could safely index them.

What bothers me more is that as far as I can work out, ParameterTuple!(T) shouldn't exist in D in its current form.  Its elements aren't types since when you use .stringof on them, they know their own storage class.  And I'm pretty sure you can't pass the tuple around without it losing the storage classes (I gave up trying to figure out exactly under which circumstances this happened and just passed the function type's stringof around.)

Maybe the underlying is() expression could be changed to return
something like (StorageDefault, int, StorageRef, int, StorageOut, out)
instead (given that the Storage* types are defined in object.d as
typedefs of void or something.)  Or maybe have a new trait or is() form
that tells us the storage classes as with a tuple of strings.  Then we
wouldn't need to rely on a spec-defying feature.

  -- Daniel
May 20, 2009
Daniel Keep wrote:
> 
> These magic tuples have a horrible habit of losing this invisible extra
> information when you so much as think about them.  I didn't realise you
> could safely index them.
> 
> What bothers me more is that as far as I can work out,
> ParameterTuple!(T) shouldn't exist in D in its current form.  Its
> elements aren't types since when you use .stringof on them, they know
> their own storage class.  And I'm pretty sure you can't pass the tuple
> around without it losing the storage classes (I gave up trying to figure
> out exactly under which circumstances this happened and just passed the
> function type's stringof around.)


This should be _much_ easier. Currently, it's way too complicated for all but the most persistent ones of us.


May 20, 2009
在 Tue, 19 May 2009 05:29:09 +0800,Jarrett Billingsley <jarrett.billingsley@gmail.com> 写道:

> On Mon, May 18, 2009 at 5:12 PM, Jarrett Billingsley
> <jarrett.billingsley@gmail.com> wrote:
>> ...
>
> Aaand for contrast, if we had __ident and static foreach:
>
> final class Finalize(T) : T
> {
> 	this(T...)(T args) if(is(typeof(new T(args)))) { super(args); }
>
> 	static foreach(member; __traits(allMembers, T))
> 		static if(__traits(isVirtualFunction, __traits(getMember, T,
> member)) && !__traits(isFinalFunction, __traits(getMember, T,
> member)))
> 			override ReturnType!(__traits(getMember, T, member))
> __ident(member)(ParameterTypeTuple!(__traits(getMember, T, member)
> args)
> 				{ return super.__ident(member)(args); }
> }

Err this sort of __ident is implemented by my patch against allMembers.

It's arranged as:

[ "membername", membersymbol, "member2name", membersymbol]
that is
__traits(allMembers, ClassSym)[1](3,4)	 would call the second member of ClassSym with args (3,4)

-- 
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
May 23, 2009
Andrei Alexandrescu wrote:
> 
> 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.
> 

 Hi,

 I don't fully understand the uses of Finalize!(C)... But for logging (or
timing), this kind of template could be useful... it think!... Anyway,
something like this:

class MagicLog(T) : T
{
// D Magic...
}

Could turn a class like this:

class C
{
   int foo() { ... }
}

to this:

class MagicLogC
{
   int foo() {
      Log.write("Entering foo()");
      scope(success) Log.write("Leaving foo(): success");
      scope(failure) Log.write("Leaving foo(): failure");
      return super.foo();
   }
}

And then, somewhere else:

version(WithMagicLog) {
   C c = new MagicLog!(C); // With logging
} else {
   C c = new C; // Full speed, no logging
}
int i = c.foo();

 Seems pretty useful to me! :) The only problem is writing the MagicLog
class.

 Guillaume B.


May 23, 2009
Guillaume B. wrote:
> Andrei Alexandrescu wrote:
>> 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.
>>
> 
>  Hi,
> 
>  I don't fully understand the uses of Finalize!(C)... But for logging (or
> timing), this kind of template could be useful... it think!... Anyway,
> something like this:
> 
> class MagicLog(T) : T
> {
> // D Magic...
> }
> 
> Could turn a class like this:
> 
> class C
> {
>    int foo() { ... }
> }
> 
> to this:
> 
> class MagicLogC
> {
>    int foo() {
>       Log.write("Entering foo()");
>       scope(success) Log.write("Leaving foo(): success");
>       scope(failure) Log.write("Leaving foo(): failure");
>       return super.foo();
>    }
> }
> 
> And then, somewhere else:
> 
> version(WithMagicLog) {
>    C c = new MagicLog!(C); // With logging
> } else {
>    C c = new C; // Full speed, no logging
> }
> int i = c.foo();
> 
>  Seems pretty useful to me! :) The only problem is writing the MagicLog
> class.

"A simple matter of programming."

It's a great idea, and a means to tap into AOP-style programming by using reflection.


Andrei
1 2 3 4 5 6
Next ›   Last »