www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - CRTP in D?

reply bearophile <bearophileHUGS lycos.com> writes:
I don't know much C++. Can CRTP be used in D1 too, to improve the performance
of some D1 code?

http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

Bye,
bearophile
Aug 19 2009
next sibling parent reply grauzone <none example.net> writes:
bearophile wrote:
 I don't know much C++. Can CRTP be used in D1 too, to improve the performance
of some D1 code?
 
 http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern
Why don't you just go and try? If you hit forward referencing errors when using structs, try classes with final methods.
 Bye,
 bearophile
Aug 19 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
grauzone:
Why don't you just go and try?<
Mostly because C++ isn't one of the languages I know. I don't fully understand that code. Bye, bearophile
Aug 19 2009
parent Kagamin <spam here.lot> writes:
bearophile Wrote:

 grauzone:
Why don't you just go and try?<
Mostly because C++ isn't one of the languages I know. I don't fully understand that code.
There's really not much to understand there. The difference from mixin is that Base can inherit an interface so that Derived exposes the interface just by deriving from Base. class Base(Derived) { void interface() { // ... (cast(Derived)this).implementation(); // ... } static void static_func() { // ... Derived.static_sub_func(); // ... } } class Derived : Base!(Derived) { void implementation(){...} static void static_sub_func(){...} }
Aug 20 2009
prev sibling parent reply downs <default_357-line yahoo.de> writes:
bearophile wrote:
 I don't know much C++. Can CRTP be used in D1 too, to improve the performance
of some D1 code?
 
 http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern
 
 Bye,
 bearophile
We have this, except we call it "template mixin" :)
Aug 19 2009
parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

downs wrote:
 bearophile wrote:
 I don't know much C++. Can CRTP be used in D1 too, to improve the performance
of some D1 code?

 http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

 Bye,
 bearophile
We have this, except we call it "template mixin" :)
No, template mixins are not CRTP. And yes CRTP does work in D. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKjDcnT9LetA9XoXwRAiN8AJ4ghcTj9sYdU7tWdQRj1vVSxPzywgCeKP6f FKwMutENm221/YmhvopIEDk= =1Zt5 -----END PGP SIGNATURE-----
Aug 19 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
On Wed, Aug 19, 2009 at 10:32 AM, div0<div0 users.sourceforge.net> wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 downs wrote:
 bearophile wrote:
 I don't know much C++. Can CRTP be used in D1 too, to improve the performance
of some D1 code?

 http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

 Bye,
 bearophile
We have this, except we call it "template mixin" :)
No, template mixins are not CRTP.
Mixins can be used to do a lot (most? all?) of things CRTP is used for: class Class(alias MixMe) { mixin MixMe impl; ... void doSomething { impl.doIt(); } }
 And yes CRTP does work in D.
That's fine if you don't need to use the one inheritance slot for something else. I also seem to recall for things like policy based design, you end up doing CRTP inheritance from several different policy classes: class Derived : Policy1<Derived>, Policy2<Derived> So I think DK is right -- more often than not CRTP is used as a substitute for lack of actual mixin support in C++. --bb
Aug 19 2009
next sibling parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bill Baxter wrote:
 On Wed, Aug 19, 2009 at 10:32 AM, div0<div0 users.sourceforge.net> wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 downs wrote:
 bearophile wrote:
 I don't know much C++. Can CRTP be used in D1 too, to improve the performance
of some D1 code?

 http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

 Bye,
 bearophile
We have this, except we call it "template mixin" :)
No, template mixins are not CRTP.
Mixins can be used to do a lot (most? all?) of things CRTP is used for: class Class(alias MixMe) { mixin MixMe impl; ... void doSomething { impl.doIt(); } }
Yes true, but there are subtle differences. I guess my no was a little over egging the differences on reflection.
 
 And yes CRTP does work in D.
That's fine if you don't need to use the one inheritance slot for something else. I also seem to recall for things like policy based design, you end up doing CRTP inheritance from several different policy classes: class Derived : Policy1<Derived>, Policy2<Derived> So I think DK is right -- more often than not CRTP is used as a substitute for lack of actual mixin support in C++. --bb
CRTP is often used that way, but it's not the only use of it. It's also used as a mechanism to create a meta interface which deriving classes need to implement. This is used quite a lot in template meta programming in c++. (and that's where you often see the multiple inheritance from policy classes you mentioned). Mixins do pretty much same thing but in reverse, mixins pull stuff right into the class, and with a mixin it's the class which is imposing the meta interface on the mixin. As you pointed out though, CRTP nukes your inheritance slot in D, so you'd generally prefer mixins in D. CRTP isn't going to give you any advantage that I can see, you just have to do your design the other way round than you would in c++. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKjFZWT9LetA9XoXwRAu7jAKDN8lOVjr1JW9F+HpWvu/rWScQIqwCguYED fVaoenX/OgKfsmXR4etVSas= =9QPj -----END PGP SIGNATURE-----
Aug 19 2009
parent bearophile <bearophileHUGS lycos.com> writes:
div0:

 Mixins do pretty much same thing but in reverse, mixins pull stuff right
 into the class, and with a mixin it's the class which is imposing the
 meta interface on the mixin.
 
 As you pointed out though, CRTP nukes your inheritance slot in D, so
 you'd generally prefer mixins in D. CRTP isn't going to give you any
 advantage that I can see, you just have to do your design the other way
 round than you would in c++.
Thank you to all the people that have answered me. Mixins have an advantage: I have understood them in minutes and then I have used them. While I haven't undertood CRTP that quickly :-) Bye, bearophile
Aug 19 2009
prev sibling next sibling parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bill Baxter wrote:
 On Wed, Aug 19, 2009 at 10:32 AM, div0<div0 users.sourceforge.net> wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 downs wrote:
 bearophile wrote:
 I don't know much C++. Can CRTP be used in D1 too, to improve the performance
of some D1 code?

 http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

 Bye,
 bearophile
We have this, except we call it "template mixin" :)
No, template mixins are not CRTP.
Mixins can be used to do a lot (most? all?) of things CRTP is used for: class Class(alias MixMe) { mixin MixMe impl; ... void doSomething { impl.doIt(); } }
While we're on the subject, is it possible to mixin in a tuple? Doesn't seem like you can... class C(M...) { mixin M; } Doesn't work. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKjGJVT9LetA9XoXwRApgoAJ9hEW/qAJ5uCR+186MfH2ebDD1zIQCaA8RT jdlbCp7Tj0oX1BMievFVXOk= =GtuO -----END PGP SIGNATURE-----
Aug 19 2009
parent reply John C <johnch_atms hotmail.com> writes:
div0 Wrote:
 
While we're on the subject, is it possible to mixin in a tuple? Doesn't seem like you can... class C(M...) { mixin M; } Doesn't work.
import std.typetuple; class C(M...) { mixin TypeTuple!(M); }
Aug 20 2009
parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

John C wrote:
 div0 Wrote:
 While we're on the subject, is it possible to mixin in a tuple?
 Doesn't seem like you can...

 class C(M...) {
  mixin M;
 }

 Doesn't work.
import std.typetuple; class C(M...) { mixin TypeTuple!(M); }
Unfortunately that doesn't work. It stops the immediate compile error, but the mixin doesn't do anything: template a() { void funcA() { writefln("funcA"); } } template b() { void funcB()() { writefln("funcB"); } } class theClass0(M ...) { mixin TypeTuple!(M); } void test() { auto g = new theClass0!(a, b); g.funcA(); g.funcB(); } main.d(31): Error: no property 'funcA' for type 'main.theClass0!(a,b).theClass0' main.d(31): Error: function expected before (), not __error of type int main.d(32): Error: no property 'funcB' for type 'main.theClass0!(a,b).theClass0' main.d(32): Error: function expected before (), not __error of type int main.d(33): Error: no property '_a' for type 'main.theClass0!(a,b).theClass0' main.d(33): Error: no property '_b' for type 'main.theClass0!(a,b).theClass0' Same with both 1.046 & 2.031 TY though. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKjaDUT9LetA9XoXwRAoo6AKDBMZC2Sc59UfDof1SSM5G9i9en6QCgk2DJ 1FMBI1zOfbuokGDx2M4ahDg= =wDXk -----END PGP SIGNATURE-----
Aug 20 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
On Thu, Aug 20, 2009 at 12:15 PM, div0<div0 users.sourceforge.net> wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 John C wrote:
 div0 Wrote:
 While we're on the subject, is it possible to mixin in a tuple?
 Doesn't seem like you can...

 class C(M...) {
 =A0mixin M;
 }

 Doesn't work.
import std.typetuple; class C(M...) { =A0 mixin TypeTuple!(M); }
Unfortunately that doesn't work. It stops the immediate compile error, but the mixin doesn't do anything:
This doesn't work either: class C(M) { mixin M; } template Foo() { void blarf() {} } auto x =3D new C!(Foo); x.blarf; because a parameter that is itself a template needs to be an alias template argument like so: class C(alias M) { ... } As far as I know you can't have an alias variadic argument or pass template aliases to a regular variadic template arg. --bb
Aug 20 2009
parent div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bill Baxter wrote:
 On Thu, Aug 20, 2009 at 12:15 PM, div0<div0 users.sourceforge.net> wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 John C wrote:
 div0 Wrote:
 While we're on the subject, is it possible to mixin in a tuple?
 Doesn't seem like you can...

 class C(M...) {
  mixin M;
 }

 Doesn't work.
import std.typetuple; class C(M...) { mixin TypeTuple!(M); }
Unfortunately that doesn't work. It stops the immediate compile error, but the mixin doesn't do anything:
This doesn't work either: class C(M) { mixin M; } template Foo() { void blarf() {} } auto x = new C!(Foo); x.blarf; because a parameter that is itself a template needs to be an alias template argument like so: class C(alias M) { ... } As far as I know you can't have an alias variadic argument or pass template aliases to a regular variadic template arg. --bb
Yup, bit of a silly limitation. I found a way to do it using our old friend: string mixins class C(string mixins) { mixin (mixins); } auto c = new C!("mixin a; mixin b;"); It's bloody ugly though. I suppose you could add some compile time functions to clean up the arg list a bit so you could do: class C(string mixins) { mixin (CrackMixins!(mixins)); } new C!("a;b"); but it's not as convenient as MI and requires class C to be written with that use in mind. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFKjcKUT9LetA9XoXwRApBMAJ0bkFN9zFmxyIhgAUgKy1q8I3aScQCggr1Q UNLHcjpF/uXbwm7+CtzsDzk= =krsn -----END PGP SIGNATURE-----
Aug 20 2009
prev sibling parent reply "Saaa" <empty needmail.com> writes:
 Mixins can be used to do a lot (most? all?) of things CRTP is used for:

 class Class(alias MixMe)
 {
   mixin MixMe impl;
   ...
   void doSomething {
         impl.doIt();
   }
 }
where can I read about class parameters?
Aug 19 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
On Wed, Aug 19, 2009 at 2:59 PM, Saaa<empty needmail.com> wrote:
 Mixins can be used to do a lot (most? all?) of things CRTP is used for:

 class Class(alias MixMe)
 {
 =A0 mixin MixMe impl;
 =A0 ...
 =A0 void doSomething {
 =A0 =A0 =A0 =A0 impl.doIt();
 =A0 }
 }
where can I read about class parameters?
It's just a class template. Short for template Class(alias MixMe) { class Class { .... } } See http://www.digitalmars.com/d/2.0/template.html under "Class Templates". --bb
Aug 19 2009
parent "Saaa" <empty needmail.com> writes:
"Bill Baxter" <wbaxter gmail.com> wrote in message 
news:mailman.344.1250719235.14071.digitalmars-d-learn puremagic.com...
On Wed, Aug 19, 2009 at 2:59 PM, Saaa<empty needmail.com> wrote:
 Mixins can be used to do a lot (most? all?) of things CRTP is used for:

 class Class(alias MixMe)
 {
 mixin MixMe impl;
 ...
 void doSomething {
 impl.doIt();
 }
 }
where can I read about class parameters?
It's just a class template. Short for template Class(alias MixMe) { class Class { .... } } See http://www.digitalmars.com/d/2.0/template.html under "Class Templates". --bb Thanks ;)
Aug 19 2009