www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Templates - Numeric Types only

reply Kevin <s.keptiker web.de> writes:
Hi,
simple Question:
Is it possible to allow just numeric types in templates?
For example to create a Vector Class like this:

class Vector(T:"numeric" = float, int size = 4)

Thanks,
Kevin
Aug 06 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:
 
 class Vector(T:"numeric" = float, int size = 4)
 
 Thanks,
 Kevin
import std.traits; class Vector(T, int size = 4) if (isNumeric!T) { ... } Andrei
Aug 06 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Aug 6, 2009 at 9:19 PM, Andrei
Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" =3D float, int size =3D 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size =3D 4) if (isNumeric!T) { =A0 =A0... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
Aug 06 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" = float, int size = 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size = 4) if (isNumeric!T) { ... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latter does not depend on the presence of the former. Andrei
Aug 06 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Aug 6, 2009 at 9:53 PM, Andrei
Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" =3D float, int size =3D 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size =3D 4) if (isNumeric!T) { =A0 ... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latt=
er
 does not depend on the presence of the former.
But the condition of the latter now depends on the condition of the former. And on the condition of any other 'specializations': struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(!isNumeric!T) {} // uhoh Vec!(string) x; // matches two Now the fallback has to be declared as struct Vec(T) if(!isNumeric!T && !isSomeString!T) {} and it gets worse the more you add.
Aug 06 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:53 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" = float, int size = 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size = 4) if (isNumeric!T) { ... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latter does not depend on the presence of the former.
But the condition of the latter now depends on the condition of the former. And on the condition of any other 'specializations': struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(!isNumeric!T) {} // uhoh Vec!(string) x; // matches two Now the fallback has to be declared as struct Vec(T) if(!isNumeric!T && !isSomeString!T) {} and it gets worse the more you add.
I know, and I explained why that's arguably better. Andrei
Aug 06 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Aug 7, 2009 at 12:54 AM, Andrei
Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:53 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" =3D float, int size =3D 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size =3D 4) if (isNumeric!T) { =A0... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latter does not depend on the presence of the former.
But the condition of the latter now depends on the condition of the former. =A0And on the condition of any other 'specializations': struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(!isNumeric!T) {} // uhoh Vec!(string) x; // matches two Now the fallback has to be declared as struct Vec(T) if(!isNumeric!T && !isSomeString!T) {} and it gets worse the more you add.
I know, and I explained why that's arguably better.
So what's the solution? Integrate template conditions into the specialization rules? Use this as a justification for their behavior? Or, like so many other features in D, leave it half-specified, half-useful, and half-implemented because "it got too hard"?
Aug 06 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Fri, Aug 7, 2009 at 12:54 AM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:53 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" = float, int size = 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size = 4) if (isNumeric!T) { ... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latter does not depend on the presence of the former.
But the condition of the latter now depends on the condition of the former. And on the condition of any other 'specializations': struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(!isNumeric!T) {} // uhoh Vec!(string) x; // matches two Now the fallback has to be declared as struct Vec(T) if(!isNumeric!T && !isSomeString!T) {} and it gets worse the more you add.
I know, and I explained why that's arguably better.
So what's the solution? Integrate template conditions into the specialization rules? Use this as a justification for their behavior?
Right now the compiler evaluates if clauses early in the matching process, eliminates those that are false, and "forgets" those that are true. It would be possible to make if-clauses an integral part of partial ordering by postulating that an instantiation originating from a matched if clause is more specialized than a template without an if-clause. That would interfere with the other partial ordering rules.
  Or, like so many other features in D, leave it half-specified,
 half-useful, and half-implemented because "it got too hard"?
Which features of D are you referring to? Andrei
Aug 06 2009
parent reply Bill Baxter <wbaxter gmail.com> writes:
On Thu, Aug 6, 2009 at 11:19 PM, Andrei
Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Fri, Aug 7, 2009 at 12:54 AM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:53 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" =3D float, int size =3D 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size =3D 4) if (isNumeric!T) { =A0... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latter does not depend on the presence of the former.
But the condition of the latter now depends on the condition of the former. =A0And on the condition of any other 'specializations': struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(!isNumeric!T) {} // uhoh Vec!(string) x; // matches two Now the fallback has to be declared as struct Vec(T) if(!isNumeric!T && !isSomeString!T) {} and it gets worse the more you add.
I know, and I explained why that's arguably better.
So what's the solution? =A0Integrate template conditions into the specialization rules? =A0Use this as a justification for their behavior?
Right now the compiler evaluates if clauses early in the matching process=
,
 eliminates those that are false, and "forgets" those that are true. It wo=
uld
 be possible to make if-clauses an integral part of partial ordering by
 postulating that an instantiation originating from a matched if clause is
 more specialized than a template without an if-clause. That would interfe=
re
 with the other partial ordering rules.

 =A0Or, like so many other features in D, leave it half-specified,
 half-useful, and half-implemented because "it got too hard"?
Which features of D are you referring to?
Design by Contract "Order of declaration doesn't matter" Protection level enforcement of various kinds Property syntax .stringof __traits Fixing the linker CTFE (in particular memory management or lack thereof) immutable (lack of data initialization) are the unfinished things that come to mind. But I would call those most of those things 90% useful / 90% implemented rather than half so. Maybe DbC is closer to half than 90%. --bb
Aug 07 2009
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
  Or, like so many other features in D, leave it half-specified,
 half-useful, and half-implemented because "it got too hard"?
Which features of D are you referring to?
Design by Contract "Order of declaration doesn't matter" Protection level enforcement of various kinds Property syntax .stringof __traits Fixing the linker CTFE (in particular memory management or lack thereof) immutable (lack of data initialization) are the unfinished things that come to mind. But I would call those most of those things 90% useful / 90% implemented rather than half so. Maybe DbC is closer to half than 90%. --bb
Others that come to mind: DIPs shared debugger support arrays
Aug 07 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jason House wrote:
 DIPs
 shared
 debugger support
 arrays
You'll be soon surprised regarding literally all of the above. But I don't want to speak again on Walter's behalf :o). Andrei
Aug 07 2009
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Bill Baxter wrote:
 On Thu, Aug 6, 2009 at 11:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Fri, Aug 7, 2009 at 12:54 AM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:53 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" = float, int size = 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size = 4) if (isNumeric!T) { ... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latter does not depend on the presence of the former.
But the condition of the latter now depends on the condition of the former. And on the condition of any other 'specializations': struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(!isNumeric!T) {} // uhoh Vec!(string) x; // matches two Now the fallback has to be declared as struct Vec(T) if(!isNumeric!T && !isSomeString!T) {} and it gets worse the more you add.
I know, and I explained why that's arguably better.
So what's the solution? Integrate template conditions into the specialization rules? Use this as a justification for their behavior?
Right now the compiler evaluates if clauses early in the matching process, eliminates those that are false, and "forgets" those that are true. It would be possible to make if-clauses an integral part of partial ordering by postulating that an instantiation originating from a matched if clause is more specialized than a template without an if-clause. That would interfere with the other partial ordering rules.
  Or, like so many other features in D, leave it half-specified,
 half-useful, and half-implemented because "it got too hard"?
Which features of D are you referring to?
Design by Contract "Order of declaration doesn't matter" Protection level enforcement of various kinds Property syntax .stringof __traits Fixing the linker CTFE (in particular memory management or lack thereof) immutable (lack of data initialization) are the unfinished things that come to mind. But I would call those most of those things 90% useful / 90% implemented rather than half so. Maybe DbC is closer to half than 90%.
Well this assessment I agree with. Note that none of the above "got too hard". One of those is compile-time function evaluation; there's such a fuzzy boundary between what works and what doesn't, that I must try some CTFE code to know whether it works. Andrei
Aug 07 2009
next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Fri, Aug 7, 2009 at 6:16 AM, Andrei
Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:

 Well this assessment I agree with. Note that none of the above "got too
 hard". One of those is compile-time function evaluation; there's such a
 fuzzy boundary between what works and what doesn't, that I must try some
 CTFE code to know whether it works.
I was referring specifically to the well-known issue with heavy CTFE code not freeing temp strings and such that are allocated by the compiler. For some CTFE code this causes the compiler to leak so much memory that the compilation slows to a crawl. To me that certainly looks like a case of "got too hard (relative to the benefit it would provide)". --bb
Aug 07 2009
prev sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Aug 7, 2009 at 9:16 AM, Andrei
Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Design by Contract
 "Order of declaration doesn't matter"
 Protection level enforcement of various kinds
 Property syntax
 .stringof
 __traits
 Fixing the linker
 CTFE (in particular memory management or lack thereof)
 immutable (lack of data initialization)

 are the unfinished things that come to mind.
 But I would call those most of those things =A090% useful / 90%
 implemented rather than half so.
 Maybe DbC is closer to half than 90%.
Well this assessment I agree with. Note that none of the above "got too hard".
I've been told *by Walter* that solving forward reference issues are difficult to solve for any real benefit. That sounds like "got too hard" to me.
Aug 07 2009
prev sibling next sibling parent Jason House <jason.james.house gmail.com> writes:
Andrei Alexandrescu Wrote:

 Jason House wrote:
 DIPs
 shared
 debugger support
 arrays
You'll be soon surprised regarding literally all of the above. But I don't want to speak again on Walter's behalf :o). Andrei
I can't even guess how you'll surprise me with DIPs. Even something like enhanced properties would be more likely due to the storm of NG chatter than a DIP. I have my fingers crossed with the other 3. I know for a fact Walter was working on gdb support since he sent me a few test executables... I did think of another item for the list: bugzilla.
Aug 07 2009
prev sibling parent Jeremie Pelletier <jeremiep gmail.com> writes:
Andrei Alexandrescu Wrote:

 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:53 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Aug 6, 2009 at 9:19 PM, Andrei
 Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:
 Kevin wrote:
 Hi,
 simple Question:
 Is it possible to allow just numeric types in templates?
 For example to create a Vector Class like this:

 class Vector(T:"numeric" = float, int size = 4)

 Thanks,
 Kevin
import std.traits; class Vector(T, int size = 4) if (isNumeric!T) { ... }
Unfortunately, struct Vec(T) if(isNumeric!T) {} struct Vec(T) {} Vec!(int) x; // error foo.d(14): Error: template instance Vec!(int) matches more than one template declaration, Vec(T) if (isNumeric!(T)) and Vec(T) *sigh* Wouldn't it be nice.
struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isNumeric!T) {} is actually superior because it's more modular; the semantics of the latter does not depend on the presence of the former.
But the condition of the latter now depends on the condition of the former. And on the condition of any other 'specializations': struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(!isNumeric!T) {} // uhoh Vec!(string) x; // matches two Now the fallback has to be declared as struct Vec(T) if(!isNumeric!T && !isSomeString!T) {} and it gets worse the more you add.
I know, and I explained why that's arguably better. Andrei
I for myself favor lots of small templates to keep function declarations shorter, for example: template isStringOrNumeric(T) { enum isStringOrNumeric = isSomeString!T || isNumeric!T; } struct Vec(T) if(isSomeString!T) {} struct Vec(T) if(isNumeric!T) {} struct Vec(T) if(!isStringOrNumeric!T) {} It also allows for the templates to have static asserts of their own to make bugs easier to isolate, and they can be moved to another file which makes for more generic programming. Chances are you'll be using the template again if you need it here. I usually try to keep my template if statements down to one or two short expressions at most, otherwise it quickly becomes more confusing than useful.
Aug 07 2009