www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template mixins: Why is the decision to mixin made at the call site?

reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Regarding template mixins, I'm curious, why is the decision to mixin a
template made at the call site and not at the declaration of the
template/mixin?

In other words, why do we write

	template foo()
	{
		// etc..
	}

	mixin foo!();

instead of

	mixin foo()
	{
		// etc..
	}

	foo!();

??

It seems to me like in most cases you determine whether or not you want
to mixin based on the contents of the template, not based on the the
calling code.  Not to mention, declaring as a mixin would allow us to
omit that mixin keyword anytime we want to do something cool with
template mixins.  So it seems odd to me as I reflect on it.
Aug 20 2009
parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Chad J wrote:
 Regarding template mixins, I'm curious, why is the decision to mixin a
 template made at the call site and not at the declaration of the
 template/mixin?
 
 In other words, why do we write
 
 	template foo()
 	{
 		// etc..
 	}
 
 	mixin foo!();
 
 instead of
 
 	mixin foo()
 	{
 		// etc..
 	}
 
 	foo!();
 
 ??
 
 It seems to me like in most cases you determine whether or not you want
 to mixin based on the contents of the template, not based on the the
 calling code.  Not to mention, declaring as a mixin would allow us to
 omit that mixin keyword anytime we want to do something cool with
 template mixins.  So it seems odd to me as I reflect on it.
Not sure what the original choice was based on, but what you suggest looks wrong to me. You aren't necessarily using a template in order to mix it in somewhere. With that syntax it looks like you can only use foo as a mixin. If you change 'mixin' to 'paste' your way round looks even more wrong. - -- 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/ iD8DBQFKjtsnT9LetA9XoXwRAipLAJ92/vE9Ofmb0sJpOqoqIYyctT6MNgCgl0IH MdLpTZ582D7iJ9j06dcTpa4= =5yW1 -----END PGP SIGNATURE-----
Aug 21 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Aug 21, 2009 at 1:36 PM, div0<div0 users.sourceforge.net> wrote:
 Not sure what the original choice was based on, but what you suggest
 looks wrong to me. You aren't necessarily using a template in order to
 mix it in somewhere.

 With that syntax it looks like you can only use foo as a mixin.
That's what he's suggesting, and it does make sense. When you write a template, *either* it's meant to be used as a mixin, *or* it's meant to be used some other way. Mixin in a template that wasn't meant to be a mixin or vice versa usually makes no sense.
 If you
 change 'mixin' to 'paste' your way round looks even more wrong.
If you're thinking of 'mixin' as a verb, "to mix in", I can understand that. But if you consider his syntax with "mixin" as a noun (like "class" or "template"), it makes more sense.
Aug 21 2009
parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jarrett Billingsley wrote:
 On Fri, Aug 21, 2009 at 1:36 PM, div0<div0 users.sourceforge.net> wrote:

 That's what he's suggesting, and it does make sense.  When you write a
 template, *either* it's meant to be used as a mixin, *or* it's meant
 to be used some other way.  Mixin in a template that wasn't meant to
 be a mixin or vice versa usually makes no sense.
Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both. - -- 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/ iD8DBQFKjt9eT9LetA9XoXwRAncVAKDMzH22eklNXIU9ec3z0LogoUSKOQCeOht1 gF0Fp+n7roln1WL/Y8Yjqek= =PRAK -----END PGP SIGNATURE-----
Aug 21 2009
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
div0 wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
 Jarrett Billingsley wrote:
 On Fri, Aug 21, 2009 at 1:36 PM, div0<div0 users.sourceforge.net> wrote:

 That's what he's suggesting, and it does make sense.  When you write a
 template, *either* it's meant to be used as a mixin, *or* it's meant
 to be used some other way.  Mixin in a template that wasn't meant to
 be a mixin or vice versa usually makes no sense.
Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both.
Can you provide an example?
Aug 21 2009
parent reply div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ary Borenszweig wrote:
 div0 wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Jarrett Billingsley wrote:
 On Fri, Aug 21, 2009 at 1:36 PM, div0<div0 users.sourceforge.net> wrote:

 That's what he's suggesting, and it does make sense.  When you write a
 template, *either* it's meant to be used as a mixin, *or* it's meant
 to be used some other way.  Mixin in a template that wasn't meant to
 be a mixin or vice versa usually makes no sense.
Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both.
Can you provide an example?
Yeah, but it's Friday night, I'm drinking beer now. :o I'll do it tomorrow. Bills response is the start of it 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/ iD8DBQFKjvdLT9LetA9XoXwRAh9QAJ9Sj/IY+xjEiJJ9QV3+fnJokyqVLQCfbARp 2IA3oDip/LxFDzhsx4cLDVw= =oNLO -----END PGP SIGNATURE-----
Aug 21 2009
parent Ary Borenszweig <ary esperanto.org.ar> writes:
div0 wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
 Ary Borenszweig wrote:
 div0 wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Jarrett Billingsley wrote:
 On Fri, Aug 21, 2009 at 1:36 PM, div0<div0 users.sourceforge.net> wrote:

 That's what he's suggesting, and it does make sense.  When you write a
 template, *either* it's meant to be used as a mixin, *or* it's meant
 to be used some other way.  Mixin in a template that wasn't meant to
 be a mixin or vice versa usually makes no sense.
Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both.
Can you provide an example?
Yeah, but it's Friday night, I'm drinking beer now. :o I'll do it tomorrow. Bills response is the start of it though.
Ah, it's ok, I saw Bill's answer later.
Aug 21 2009
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 21 Aug 2009 13:54:38 -0400, div0 <div0 users.sourceforge.net>  
wrote:

 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Jarrett Billingsley wrote:
 On Fri, Aug 21, 2009 at 1:36 PM, div0<div0 users.sourceforge.net> wrote:

 That's what he's suggesting, and it does make sense.  When you write a
 template, *either* it's meant to be used as a mixin, *or* it's meant
 to be used some other way.  Mixin in a template that wasn't meant to
 be a mixin or vice versa usually makes no sense.
Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both.
What you could have is similar to scope classes, that is, if you define a template as a mixin template, it's always meant to be a mixin (which is a common case). Now, scope classes must be declared as scope when used, so does it make sense to require mixin templates to be called via mixin? I'm not sure, it would be against what the O.P. desired, but seeing the mixin keyword at the usage site is a huge documentation hint. I do see value in declaring a template as a mixin template, making it an error to use it as a normal template. -Steve
Aug 21 2009
parent div0 <div0 users.sourceforge.net> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Steven Schveighoffer wrote:
 On Fri, 21 Aug 2009 13:54:38 -0400, div0 <div0 users.sourceforge.net>
 wrote:
 
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Jarrett Billingsley wrote:
 On Fri, Aug 21, 2009 at 1:36 PM, div0<div0 users.sourceforge.net> wrote:

 That's what he's suggesting, and it does make sense.  When you write a
 template, *either* it's meant to be used as a mixin, *or* it's meant
 to be used some other way.  Mixin in a template that wasn't meant to
 be a mixin or vice versa usually makes no sense.
Hmmm. Not convinced by that argument, I can think of good reasons to use a template as both.
What you could have is similar to scope classes, that is, if you define a template as a mixin template, it's always meant to be a mixin (which is a common case). Now, scope classes must be declared as scope when used, so does it make sense to require mixin templates to be called via mixin? I'm not sure, it would be against what the O.P. desired, but seeing the mixin keyword at the usage site is a huge documentation hint. I do see value in declaring a template as a mixin template, making it an error to use it as a normal template. -Steve
That would be nice. You can sort of bodge that at the mo. Just stick a const method in the template, then if you try and use it outside a class/struct the compiler barfs. Though really that needs to change; it's inconsistent. - -- 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/ iD8DBQFKj72nT9LetA9XoXwRAiBsAJ4/N0S1gzR+LaVnINd9eVHei5lHYgCfVmQi c5FDCV9/TvqFHyY6FMhRvzg= =R2Bs -----END PGP SIGNATURE-----
Aug 22 2009
prev sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Fri, Aug 21, 2009 at 10:36 AM, div0<div0 users.sourceforge.net> wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Chad J wrote:
 Regarding template mixins, I'm curious, why is the decision to mixin a
 template made at the call site and not at the declaration of the
 template/mixin?

 In other words, why do we write

 =A0 =A0 =A0 template foo()
 =A0 =A0 =A0 {
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 // etc..
 =A0 =A0 =A0 }

 =A0 =A0 =A0 mixin foo!();

 instead of

 =A0 =A0 =A0 mixin foo()
 =A0 =A0 =A0 {
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 // etc..
 =A0 =A0 =A0 }

 =A0 =A0 =A0 foo!();

 ??

 It seems to me like in most cases you determine whether or not you want
 to mixin based on the contents of the template, not based on the the
 calling code. =A0Not to mention, declaring as a mixin would allow us to
 omit that mixin keyword anytime we want to do something cool with
 template mixins. =A0So it seems odd to me as I reflect on it.
Not sure what the original choice was based on, but what you suggest looks wrong to me. You aren't necessarily using a template in order to mix it in somewhere. With that syntax it looks like you can only use foo as a mixin. If you change 'mixin' to 'paste' your way round looks even more wrong.
At least for templates that are just a bunch of alias declarations, it can be handy to be able to use directly or to mix in. So there would be little to be gained by forcing the developer to choose "mixin" or "regular template" up front. For example template MeshTypes(MeshType) { alias MeshType mesh_type alias typeof(MeshType.vertices[0]) vert_type; alias typeof(MeshType.vertices[0].x) float_type; const uint vert_dim =3D vert_type.length; } That's handy to use inline like MeshTypes!(MyMesh).vert_type Or you can mix it in to another class that uses mesh a lot to have all those types defined inside your class too. --bb
Aug 21 2009
parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Bill Baxter wrote:
 On Fri, Aug 21, 2009 at 10:36 AM, div0<div0 users.sourceforge.net> wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Not sure what the original choice was based on, but what you suggest
 looks wrong to me. You aren't necessarily using a template in order to
 mix it in somewhere.

 With that syntax it looks like you can only use foo as a mixin. If you
 change 'mixin' to 'paste' your way round looks even more wrong.
At least for templates that are just a bunch of alias declarations, it can be handy to be able to use directly or to mix in. So there would be little to be gained by forcing the developer to choose "mixin" or "regular template" up front. For example template MeshTypes(MeshType) { alias MeshType mesh_type alias typeof(MeshType.vertices[0]) vert_type; alias typeof(MeshType.vertices[0].x) float_type; const uint vert_dim = vert_type.length; } That's handy to use inline like MeshTypes!(MyMesh).vert_type Or you can mix it in to another class that uses mesh a lot to have all those types defined inside your class too. --bb
Alright, good example. But then why not: mixin MeshTypes(MeshType) { alias MeshType mesh_type alias typeof(MeshType.vertices[0]) vert_type; alias typeof(MeshType.vertices[0].x) float_type; const uint vert_dim = vert_type.length; } template MeshTypesOf(MeshType) { mixin MeshTypes!(MeshType); } Admittedly it is not as clean and violates DRY some. But it does allow the declarer to explicitly determine how the template/mixin gets used. Eh, I was kinda hoping for a reason better than "there are some cases where you want both a mixin and a template to be the same thing." I thought it might be something obvious to someone; something that I missed. Nonetheless, the template/mixin duality seems fairly benign, so this decision is starting to look somewhat arbitrary to me.
Aug 23 2009