www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Nobody understands templates?

reply "Steve Teale" <steve.teale britseyeview.com> writes:
All the D aficionados seem to wet their pants over
meta-programming, but I struggle to find a place to use it.

IIRC, I used it in a couple of places when I was trying to write
library stuff for MySQL, but in my current project, I use it only
once. That's when I want to stuff something onto my undo stack.

For that I have two template functions - push(T)(MybaseClass* p,
T t, int ID), and pushC, which is just the same except that it
checks the top of the stack to see if the ID there is the same as
what it is wanting to push.

This has served me very reliably, but I struggle to find other
places in the whole application where I would benefit from
templates.

Is this typical - libraries use templates, applications don't, or
am I just being unimaginative?

Steve
Feb 28 2014
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
A lot of my code doesn't use very many new templates either... my 
web code does use a few magic templates which fills in a lot of 
boilerplate, but the app code - the business logic - uses almost 
no templates at all. My xml/html dom.d library also uses very few 
templates, it just doesn't fit as well as plain classes there.

I think it just depends on what you're doing... if it's generic 
or boilerplate, templates rock, but much of a program isn't 
really generic.
Feb 28 2014
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 Is this typical - libraries use templates, applications don't, 
 or
 am I just being unimaginative?

 Steve
It is quite true as a generalization but in practice border line between application and a library is not that clear. You often have common modules used in various parts of an application. Kind of internal mini-libraries. Also every time you catch yourself doing any sort of copy-paste, it is quite possible that it can be replaced by mixin / template mixin instead. Application that are built in more declarative way benefit more from such tool set than traditional imperative ones.
Feb 28 2014
parent reply "Steve Teale" <steve.teale britseyeview.com> writes:
On Friday, 28 February 2014 at 19:06:26 UTC, Dicebot wrote:
 On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 Is this typical - libraries use templates, applications don't, 
 or
 am I just being unimaginative?

 Steve
 Also every time you catch yourself doing any sort of 
 copy-paste, it is quite possible that it can be replaced by 
 mixin / template mixin instead. Application that are built in 
 more declarative way benefit more from such tool set than 
 traditional imperative ones.
In have a couple of case that always require me to find some other instance of it, and then copy/paste, But then I need to edit the pasted code anyway because in any particular case it needs to deal with different command info, so how can mixins help me? I have already dealt with the yada-yada cases by old-fashioned OOP. From the various answers to this question I have concluded that I should not worry about it. If there's a need for a template I think I am already recognizing it. Thanks!all() Steve
Mar 01 2014
next sibling parent reply "woh" <wojw yahoo.com> writes:
  You probably don't have a good understanding of templates if you 
have only used 2 in your entire codebase.  Or you are talking 
about a very tiny codebase.



n Saturday, 1 March 2014 at 18:00:21 UTC, Steve Teale wrote:
 On Friday, 28 February 2014 at 19:06:26 UTC, Dicebot wrote:
 On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 Is this typical - libraries use templates, applications 
 don't, or
 am I just being unimaginative?

 Steve
 Also every time you catch yourself doing any sort of 
 copy-paste, it is quite possible that it can be replaced by 
 mixin / template mixin instead. Application that are built in 
 more declarative way benefit more from such tool set than 
 traditional imperative ones.
In have a couple of case that always require me to find some other instance of it, and then copy/paste, But then I need to edit the pasted code anyway because in any particular case it needs to deal with different command info, so how can mixins help me? I have already dealt with the yada-yada cases by old-fashioned OOP. From the various answers to this question I have concluded that I should not worry about it. If there's a need for a template I think I am already recognizing it. Thanks!all() Steve
Mar 01 2014
parent reply "Steve Teale" <steve.teale britseyeview.com> writes:
On Saturday, 1 March 2014 at 22:16:54 UTC, woh wrote:
  You probably don't have a good understanding of templates if 
 you have only used 2 in your entire codebase.  Or you are 
 talking about a very tiny codebase.
That's just what us template-blind people want to hear - confirmation that we are in fact stupid. The project I'm talking about is about 30000 loc excluding blank lines and comments. What I'd like to see is a tool, or a switch on the compiler that emits the code generated by templates. We - the template-blind - would have it sussed in a heartbeat then. Steve
Mar 01 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Sunday, 2 March 2014 at 06:50:02 UTC, Steve Teale wrote:
 On Saturday, 1 March 2014 at 22:16:54 UTC, woh wrote:
 You probably don't have a good understanding of templates if 
 you have only used 2 in your entire codebase.  Or you are 
 talking about a very tiny codebase.
That's just what us template-blind people want to hear - confirmation that we are in fact stupid. The project I'm talking about is about 30000 loc excluding blank lines and comments. What I'd like to see is a tool, or a switch on the compiler that emits the code generated by templates. We - the template-blind - would have it sussed in a heartbeat then. Steve
There is nothing wrong about not using templates. Almost any compile-time design can be moved to run-time and expressed in more common OOP form. And using tool you have mastery of is usually more beneficial in practice than following the hype.
Mar 02 2014
parent reply "Steve Teale" <steve.teale britseyeview.com> writes:
On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:

 There is nothing wrong about not using templates. Almost any 
 compile-time design can be moved to run-time and expressed in 
 more common OOP form. And using tool you have mastery of is 
 usually more beneficial in practice than following the hype.
Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve
Mar 02 2014
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:
 On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:

 There is nothing wrong about not using templates. Almost any 
 compile-time design can be moved to run-time and expressed in 
 more common OOP form. And using tool you have mastery of is 
 usually more beneficial in practice than following the hype.
Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve
This is quite a nice read on D templates: http://ddili.org/ders/d.en/templates.html
Mar 02 2014
prev sibling next sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:
 The documentation examples quickly make your eyes glaze over, 
 looking at the code in Phobos is doubtless instructive, but you 
 can wade through a lot of that without finding what you want.
Try this: http://nomad.so/2013/07/templates-in-d-explained/
Mar 02 2014
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Mar 02, 2014 at 11:47:38AM +0000, Steve Teale wrote:
 On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:
 
There is nothing wrong about not using templates. Almost any
compile-time design can be moved to run-time and expressed in more
common OOP form. And using tool you have mastery of is usually
more beneficial in practice than following the hype.
Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want.
This is a pretty good primer to templates: https://semitwist.com/articles/article/view/template-primer-in-d T -- Дерево держится корнями, а человек - друзьями.
Mar 02 2014
parent reply "Steve Teale" <steve.teale britseyeview.com> writes:
On Sunday, 2 March 2014 at 15:23:03 UTC, H. S. Teoh wrote:
 This is a pretty good primer to templates:

 	https://semitwist.com/articles/article/view/template-primer-in-d
The trouble is with most of these tutorials that they offer examples that are things you would probably never want to do. I can already add an int to an int, or a double to a double, or an int to a double. Perhaps the examples should pick on something like vector operations, but then who would be doing those with int, or some class? It would be doubles or pairs of, as in struct Coord. I believe readers would study documentation and examples much more carefully if they were things they might realistically want to do. And that won't be type conversion - std.conv already does a pretty good job on that. So what? We could really do with a place where template savvy open source contributors could publish interesting examples of template use. Otherwise, Joe Soap, like me, can spend a great deal of time and effort in: a) Determining when the use of a template might be advantageous, b) Hacking at test programs to determine what the documentation means, and what works, and what doesn't. c) After that, deciding whether it would be just as effective to use two or three separate methods. Steve Steve
Mar 02 2014
next sibling parent reply "Chris" <wendlec tcd.ie> writes:
On Sunday, 2 March 2014 at 18:59:23 UTC, Steve Teale wrote:
 On Sunday, 2 March 2014 at 15:23:03 UTC, H. S. Teoh wrote:
 This is a pretty good primer to templates:

 	https://semitwist.com/articles/article/view/template-primer-in-d
The trouble is with most of these tutorials that they offer examples that are things you would probably never want to do. I can already add an int to an int, or a double to a double, or an int to a double. Perhaps the examples should pick on something like vector operations, but then who would be doing those with int, or some class? It would be doubles or pairs of, as in struct Coord. I believe readers would study documentation and examples much more carefully if they were things they might realistically want to do. And that won't be type conversion - std.conv already does a pretty good job on that. So what? We could really do with a place where template savvy open source contributors could publish interesting examples of template use. Otherwise, Joe Soap, like me, can spend a great deal of time and effort in: a) Determining when the use of a template might be advantageous, b) Hacking at test programs to determine what the documentation means, and what works, and what doesn't. c) After that, deciding whether it would be just as effective to use two or three separate methods. Steve Steve
I'm always willing to use templates, but maybe in fact the use cases are limited. I have a class for html elements (that implements DOM functionality), and a class for building trees with the tags. Of course, for html tags only string as a type makes sense. class Element(T) { } or class HTMLElement(T) if (is (T == string)) { } Tree(T) { } I implemented it as a template, because I thought it might be useful for other types as well, if I want to build a hierarchical tree of extracted data, be it integers, floating point numbers or whatever at a later point. However, I don't know a) if this will ever be the case and b) if I won't have to modify the template to adapt to new data types (which kinda defeats the purpose). I'm not against templates, I'm just not sure, if there are so many general or generalizable cases in programming for which templates are _the_ solution.
Mar 03 2014
parent reply "Dominikus Dittes Scherkl" writes:
On Monday, 3 March 2014 at 16:40:09 UTC, Chris wrote:
 I'm always willing to use templates, but maybe in fact the use 
 cases are limited. I have a class for html elements (that 
 implements DOM functionality), and a class for building trees 
 with the tags. Of course, for html tags only string as a type 
 makes sense.
Really? Did you consider that there are three different flavors of "string"? Does your function really only deal with string? Or would someone need wstring or dstring?
 class HTMLElement(T) if (is (T == string)) {

 }

 [...] I don't know [...] if I won't have to modify the template 
 to adapt to new data types (which kinda defeats the purpose).
Not much if the different types have common features. Most times it is still a big save of code to implement, even if the types need to be handled different in some places.
Mar 03 2014
parent "Chris" <wendlec tcd.ie> writes:
On Monday, 3 March 2014 at 17:24:08 UTC, Dominikus Dittes Scherkl 
wrote:
 On Monday, 3 March 2014 at 16:40:09 UTC, Chris wrote:
 I'm always willing to use templates, but maybe in fact the use 
 cases are limited. I have a class for html elements (that 
 implements DOM functionality), and a class for building trees 
 with the tags. Of course, for html tags only string as a type 
 makes sense.
Really? Did you consider that there are three different flavors of "string"? Does your function really only deal with string? Or would someone need wstring or dstring?
Good point. Of course! I was thinking in an abstract way of "string".
 class HTMLElement(T) if (is (T == string))

 }

 [...] I don't know [...] if I won't have to modify the 
 template to adapt to new data types (which kinda defeats the 
 purpose).
Not much if the different types have common features. Most times it is still a big save of code to implement, even if the types need to be handled different in some places.
But it's no longer a template then, is it?
Mar 03 2014
prev sibling parent reply "sclytrack" <sclytrack fake.com> writes:
On Sunday, 2 March 2014 at 18:59:23 UTC, Steve Teale wrote:
 On Sunday, 2 March 2014 at 15:23:03 UTC, H. S. Teoh wrote:
 This is a pretty good primer to templates:

 	https://semitwist.com/articles/article/view/template-primer-in-d
The trouble is with most of these tutorials that they offer examples that are things you would probably never want to do. I can already add an int to an int, or a double to a double, or an int to a double. Perhaps the examples should pick on something like vector operations, but then who would be doing those with int, or some class? It would be doubles or pairs of, as in struct Coord.
import std.stdio; import std.algorithm; void add(T,size_t N)(ref T[N] result, const T[N] a, const T[N] b) { result[0] = a[0]+b[0]; static if (N > 1) result[1]=a[1]+b[1]; } void main() { int [2] a = [1,2]; int [2] b= [3,4]; int [2] result; result.add(a,b); writeln(result); result[] = a[] + b[]; writeln(result); }
 I believe readers would study documentation and examples much 
 more carefully if they were things they might realistically 
 want to do. And that won't be type conversion - std.conv 
 already does a pretty good job on that. So what?

 We could really do with a place where template savvy open 
 source contributors could publish interesting examples of 
 template use.

 Otherwise, Joe Soap, like me, can spend a great deal of time 
 and effort in:

 a) Determining when the use of a template might be advantageous,
 b) Hacking at test programs to determine what the documentation 
 means, and what works, and what doesn't.
 c) After that, deciding whether it would be just as effective 
 to use two or three separate methods.

 Steve


 Steve
Are there any disadvantages of using a fixed size array for fixed size coordinates and vectors, over creating an actual typedef or struct Vec3?
Mar 05 2014
parent reply "develop32" <develop32 gmail.com> writes:
On Wednesday, 5 March 2014 at 22:46:40 UTC, sclytrack wrote:
 Are there any disadvantages of using a fixed size array for 
 fixed size
 coordinates and vectors, over creating an actual typedef or 
 struct Vec3?
Don't know what's the current situation in druntime, but when I tried static arrays a while ago in my engine every second there were megabytes of garbage generated. I ended up using structs with fields.
Mar 05 2014
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Mar 05, 2014 at 11:31:12PM +0000, develop32 wrote:
 On Wednesday, 5 March 2014 at 22:46:40 UTC, sclytrack wrote:
Are there any disadvantages of using a fixed size array for fixed
size coordinates and vectors, over creating an actual typedef or
struct Vec3?
Don't know what's the current situation in druntime, but when I tried static arrays a while ago in my engine every second there were megabytes of garbage generated. I ended up using structs with fields.
Whoa. What did you do with those arrays?? Either you did something wrong, or there's a nasty bug somewhere in the compiler/language; AFAIK static arrays are supposed to be value types so they shouldn't generate any garbage at all. T -- A computer doesn't mind if its programs are put to purposes that don't match their names. -- D. Knuth
Mar 05 2014
parent reply "develop32" <develop32 gmail.com> writes:
On Wednesday, 5 March 2014 at 23:47:33 UTC, H. S. Teoh wrote:
 Whoa. What did you do with those arrays?? Either you did 
 something
 wrong, or there's a nasty bug somewhere in the 
 compiler/language; AFAIK
 static arrays are supposed to be value types so they shouldn't 
 generate
 any garbage at all.
I think it was the case of using array literals, like this (I didn't know much about D back then) this(float x, float y, float z) { this.vector = [x, y, z]; } And megabytes accumulated because there were hundreds of objects all doing complicated stuff every frame, passing and constructing vectors and matrices around. Memory leaks could have been avoided, but still, one should be careful when using arrays.
Mar 05 2014
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Mar 06, 2014 at 12:02:42AM +0000, develop32 wrote:
 On Wednesday, 5 March 2014 at 23:47:33 UTC, H. S. Teoh wrote:
Whoa. What did you do with those arrays?? Either you did something
wrong, or there's a nasty bug somewhere in the compiler/language;
AFAIK static arrays are supposed to be value types so they shouldn't
generate any garbage at all.
I think it was the case of using array literals, like this (I didn't know much about D back then) this(float x, float y, float z) { this.vector = [x, y, z]; }
I assume this.vector is a float[3]? Yeah, this is one of the things in D that I find disappointing. Array literals are a minefield of hidden allocations and runtime performance hits. In theory, the compiler *should* realize that since this.vector is a static array, it should just assign x, y, z directly to the array elements. But IIRC (assuming the compiler hasn't changed in this respect) what it actually does is to construct a *dynamic* array [x, y, z] and then assign it to the static array. Which, of course, produces huge amounts of garbage. And which kinda defeats the purpose of using static arrays in the first place... :-(
 And megabytes accumulated because there were hundreds of objects all
 doing complicated stuff every frame, passing and constructing
 vectors and matrices around.
 
 Memory leaks could have been avoided, but still, one should be
 careful when using arrays.
A recent idiom of mine: struct Vector(T, size_t n) { T[n] impl; alias impl this; this(Args...)(Args args) if (Args.length == n) { // This is compile-time unrolled foreach (i, arg; args) { impl[i] = arg; } } } T -- The two rules of success: 1. Don't tell everything you know. -- YHL
Mar 05 2014
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
 https://semitwist.com/articles/article/view/template-primer-in-d
 http://nomad.so/2013/07/templates-in-d-explained/
 http://ddili.org/ders/d.en/templates.html
That's a nice list. Is there a place on the wiki where these could be linked to?
Mar 02 2014
prev sibling next sibling parent reply "Frustrated" <Frustrated nowhere.com> writes:
On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:
 On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:

 There is nothing wrong about not using templates. Almost any 
 compile-time design can be moved to run-time and expressed in 
 more common OOP form. And using tool you have mastery of is 
 usually more beneficial in practice than following the hype.
Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve
You've got to learn to think a bit more abstractly. Templates are generalizations of things. Suppose I want to add two numbers using a function. int add(int, int)? double add(double, int)? float add(float, int)? char add(char, double)? etc.... which one? Do you want to have to create a function every time for every time? Whats the only significant difference between all of them? If you can't answer this then you can't abstract and which is the reason you don't understand templates. I could use one template function to handle all those cases above. That's what makes it powerful. I can basically write one function when you have to write 8, 10, 20 or whatever. S add(S, T)(S a, T b) { return cast(S)(a + b); } The compiler then generates all the concrete use cases for me. (and using oop can make it more powerful, S and T could be vectors) As long as the first type has an binary addition operator on it that takes the second type it will work and the template will work without change. But you want to continue using the hold way. It is analogous to those that want to continue to write procedural code because they don't see the what oop has to offer. BTW, how did you learn oop? Did you understand it all perfectly by reading a book or did you learn best by writing code that used it? If you don't attempt to use templates, even in example code, you won't get it.
Mar 03 2014
next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote:
 If you don't attempt to use templates, even in example code, 
 you won't get it.
What I don't get in this discussion is that all those fine phobos examples are neglected. Yes, it is library code, but writef/formattedWrite/std.conv.to, std.container, std.range, std.algorithm are only possible with meta-programming and are fine examples of the usefulness of templates. This thread looks like this to me: I bought a new hammer, but not everything is a nail. Give me back my money!
Mar 03 2014
prev sibling parent reply "Chris" <wendlec tcd.ie> writes:
On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote:
 On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:
 On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:

 There is nothing wrong about not using templates. Almost any 
 compile-time design can be moved to run-time and expressed in 
 more common OOP form. And using tool you have mastery of is 
 usually more beneficial in practice than following the hype.
Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve
You've got to learn to think a bit more abstractly. Templates are generalizations of things.
I think the problem is not that people don't understand templates in the sense that they are abstractions. The question is whether there are loads and loads of use cases for them.
 Suppose I want to add two numbers using a function.

 int add(int, int)?
 double add(double, int)?
 float add(float, int)?
 char add(char, double)?
 etc....

 which one? Do you want to have to create a function every time 
 for every time?
This is a typical use case and always mentioned in tutorials. The question is how many of these "typical" cases one encounters while writing software. I think another problem with templates is that it is not always clear what is abstracted. The type or the logic? Both? In the above example the logic remains the same and is reproduced by the compiler for each type. Sometimes the logic can be abstracted for which type independence is important. But I'm not sure if that can be called a template in the purest sense. E.g. an algorithm that finds the first instance of something might be different for each type (string, char, int) and the "abstract" implementation has to differentiate internally (if string > else if int > else if ...). But this is no longer a template, or is it? [snip]
Mar 03 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote:
 E.g. an algorithm that finds the first instance of something 
 might be different for each type (string, char, int) and the 
 "abstract" implementation has to differentiate internally (if 
 string > else if int > else if ...). But this is no longer a 
 template, or is it?
What makes you think so? Template with specializations is still a template.
Mar 03 2014
parent reply "Chris" <wendlec tcd.ie> writes:
On Monday, 3 March 2014 at 19:32:51 UTC, Dicebot wrote:
 On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote:
 E.g. an algorithm that finds the first instance of something 
 might be different for each type (string, char, int) and the 
 "abstract" implementation has to differentiate internally (if 
 string > else if int > else if ...). But this is no longer a 
 template, or is it?
What makes you think so? Template with specializations is still a template.
Maybe I'm a bit too philosophical about this. But consider the following (made up) case: struct MyTemp(T) { // ... T add(T a, T b) { if (a is string && b is string) { return a~b; // or return a~"+"~b; or whatever } else if (a is integer && a is integer) { return a+b; } } } I don't know if this can be considered a "pure" template. It is a template of sorts, but the type specialization in the function add makes it a watered-down template, imo. You could have a version of MyTemp that handles only strings (and dchars, wchars) and one that handles only numbers. But this you also have in OO where this is achieved by inheritance and interfaces. I think the confusion about templates often arises from the fact that it is mainly about types, i.e. that the compiler fills in the template with the appropriate type. But it is not an abstraction of the logic behind a function. The logic in a+b is the same for int + int; float + float; float + int ... and thus not an abstraction of adding one thing to another. It is different for string + string. Of course, we can have separate templates, one for numbers, one for strings, one for arrays etc. But then it is less general. I am not against templates, far from it, I like them, and std.algorithm is a brilliant example of how useful they are. However, I wonder to what extent they can be useful when writing a specialized program as opposed to a general library. Walter mentioned that he uses them a lot these days. How? I want to learn.
Mar 03 2014
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 3/3/2014 5:35 PM, Chris wrote:
 Maybe I'm a bit too philosophical about this. But consider the following
 (made up) case:

 struct MyTemp(T) {
      // ...
      T add(T a, T b) {
          if (a is string && b is string) {
                return a~b;  // or return a~"+"~b; or whatever
          } else if (a is integer && a is integer) {
                return a+b;
          }
      }
 }

 I don't know if this can be considered a "pure" template. It is a
 template of sorts, but the type specialization in the function add makes
 it a watered-down template,
Any useful template function already works that way. The mere + operator is *not* one single operation, but a whole category of opcodes which are chosen based on the operand's type. Thus, + can be thought of as a built-in template that [roughly] does this: T opPlus(T a, T b) { if (T is integer) { [asm opcode for 32-bit addition] a, b } else if (T is ubyte) { [asm opcode for 8-bit addition] a, b } else if (T is float) { [asm opcode for floating point addition] a, b } } Specialization is what makes function templates useful. Some of the specialization is explicit (static if) and some is implicit (+ operator). But without specialization (explicit or implicit), all instantiations would be identical. If all instantiations are identical, why even have a template in the first place?
Mar 04 2014
parent "Chris" <wendlec tcd.ie> writes:
On Wednesday, 5 March 2014 at 02:28:00 UTC, Nick Sabalausky wrote:
 On 3/3/2014 5:35 PM, Chris wrote:
 Maybe I'm a bit too philosophical about this. But consider the 
 following
 (made up) case:

 struct MyTemp(T) {
     // ...
     T add(T a, T b) {
         if (a is string && b is string) {
               return a~b;  // or return a~"+"~b; or whatever
         } else if (a is integer && a is integer) {
               return a+b;
         }
     }
 }

 I don't know if this can be considered a "pure" template. It 
 is a
 template of sorts, but the type specialization in the function 
 add makes
 it a watered-down template,
Any useful template function already works that way. The mere + operator is *not* one single operation, but a whole category of opcodes which are chosen based on the operand's type. Thus, + can be thought of as a built-in template that [roughly] does this: T opPlus(T a, T b) { if (T is integer) { [asm opcode for 32-bit addition] a, b } else if (T is ubyte) { [asm opcode for 8-bit addition] a, b } else if (T is float) { [asm opcode for floating point addition] a, b } } Specialization is what makes function templates useful. Some of the specialization is explicit (static if) and some is implicit (+ operator). But without specialization (explicit or implicit), all instantiations would be identical. If all instantiations are identical, why even have a template in the first place?
Yes, this is perfectly clear to me. But the opcodes only matter to the compiler not to the programmer, i.e. the logical concept that one number (integer, float ...) is added to another remains the same. That's what I was saying. The use of templates to avoid code duplication has been mentioned (cf. Sean Kelly's post), however real duplication is rare in specialized programs, because each function or method has it's own specialized job, else we wouldn't have them. Even if we suppose that we might want to cater for string, dchar, wchar without having to write the function three times, there might be slight differences in handling the three types so we have to fork within the template. What you are basically doing then is to pack three different functions (or the parts in which they differ) in one, at programming time (not compile time). This means you introduce three _different_ types of logic / handling mechanisms. Philosophically this is not a pure template, imo. The question is where does it end? Can you turn the whole program into one big template that handles all the different types and types of logic? (Exaggerating :-) The example I showed above is maybe not so far fetched add(int, int) and add(string, string). The points you made above about OOP are very good and I'm increasingly unhappy with OOP's limitations. However, turning to templates I find myself stuck sometimes too, and I don't feel good about "compromising" a template by using too many if's for different types or introducing new logic that should actually go into a separate function / method. I'm really interested in different approaches like templates and entities, especially if they help optimizing code for processors and memory. However, I sometimes think that in Software development we always hit the same wall, whether we go from assembly to C, to OOP, to templates. The wall is that every real world program is highly unique and specialized and abstraction goes only so far. One good use for templates, I figure, would be writing an interpreter for a scripting or DSL. As in: greeting = "Hello, " + "world!"; result = 1 + 1; greeting = add(string, string) result = add(int, int)
Mar 05 2014
prev sibling parent reply "Frustrated" <Frustrated nowhere.com> writes:
On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote:
 On Monday, 3 March 2014 at 18:03:12 UTC, Frustrated wrote:
 On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:
 On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:

 There is nothing wrong about not using templates. Almost any 
 compile-time design can be moved to run-time and expressed 
 in more common OOP form. And using tool you have mastery of 
 is usually more beneficial in practice than following the 
 hype.
Yes DB, we can soldier on happily, but it would not do any harm to understand templates. The documentation examples quickly make your eyes glaze over, looking at the code in Phobos is doubtless instructive, but you can wade through a lot of that without finding what you want. Also I discovered an interesting fact today. the word 'mixin' does not appear in the language reference Templates section of dlang.org. It should be used in at least one example. I just discovered by trial and error that I could use 'mixin' in Templates (as opposed to Template Mixins), and when you know that it seems likely that you can accomplish lots of stuff you couldn't before. While I'm here, has anyone discovered a way to fudge a constructor super(..) call in a mixin template that's included in a class constructor. Since the mixin template is evaluated in the scope of the constructor, it seems like it should be OK. I'm sure I'll get there in time ;=) Steve
You've got to learn to think a bit more abstractly. Templates are generalizations of things.
I think the problem is not that people don't understand templates in the sense that they are abstractions. The question is whether there are loads and loads of use cases for them.
It is irrelevant if there are loads and loads of use cases for them. Just because people don't use something doesn't mean it is useless.
 Suppose I want to add two numbers using a function.

 int add(int, int)?
 double add(double, int)?
 float add(float, int)?
 char add(char, double)?
 etc....

 which one? Do you want to have to create a function every time 
 for every time?
This is a typical use case and always mentioned in tutorials. The question is how many of these "typical" cases one encounters while writing software.
Look at the STL library if you do't believe templates are useful...
 I think another problem with templates is that it is not always 
 clear what is abstracted. The type or the logic? Both? In the 
 above example the logic remains the same and is reproduced by 
 the compiler for each type. Sometimes the logic can be 
 abstracted for which type independence is important. But I'm 
 not sure if that can be called a template in the purest sense. 
 E.g. an algorithm that finds the first instance of something 
 might be different for each type (string, char, int) and the 
 "abstract" implementation has to differentiate internally (if 
 string > else if int > else if ...). But this is no longer a 
 template, or is it?
Both logic and types are abtracted. Even though the template might use the same operator, the compiler must determine which concrete operator to use. The addition between the two abstract objects also requires an abstract operator. The great thing is, because the abstract logic is identical("adding two things") makes the template actually useful. If it wasn't we would have to specialize the template for all the different possible binary combinations and then it would defeat the simplification that abstract is suppose to offer. The the logical process is used when one looks at procedural code and realizes that one can "simplify" it by using oop. Templates give you the same power over oop that oop gives over non-oop. But just because templates[oop] are available doesn't mean you have to use it or it is always the best solution. I use templates all the time. I create them to simplify some task then put them in a library. For me, templates allow me to streamline things that I couldn't otherwise do. Any time I feel like something is being repeated a lot I automatically think that a templates will help. I hate "copying and pasting" and so I tend to use templates a lot. One of the main uses of templates is compile time type safety. This is necessary with oop because oop allows one to create types at compile time. Hence, the need to be able to make your oop "safe" is a natural step and templates help you accomplish that. e.g., Array's of objects vs Array's of a Type. One is much safer, informs the about what your intentions are so it can make better informed decisions. e.g., Array!Type allows the Array to determine if the Type supports certain things at **compile time**. Array!Object can't do this at compile time. If you can't see the benefit of Array!Type vs Array!Object then you are beyond help. (this is not to say Array!Object is always useless, but it is the most generic you can get and the compiler can do little to help the situation) I'll give you a simple example: One could create an Array type that allows one to traverse the array in a multitude of ways. Suppose the objects stored by the arrays are arrays themselves. If the Array is templated it could easily figure this out and create an iterator that iterates over the sub-array(calling its iterator). This way one could easily display a flat list of the array [of arrays [of arrays ...]]. Because the Array type could figure out all this at compile time it would be way more efficient than having to use run-time reflection to determine of the object is an array and if it has the iterator. (it would also be easier to code) Basically you have the choice: ------------ <- "template" way of thinking (more general than oop) -------- <- Oop way of thinking (more general than procedural) ----- <- procedural way of thinking... "Old School" - <- Punch Cards (it's not quite that simple as templates or more of an offshoot of oop) If you are thinking at the template level then you will know when to use templates. If you are thinking at the oop level, you always go for your oop hammer(duh, cause everything looks like an oop nail). If you are thinking at the procedural level then you always try to solve problems in the procedural way. I prefer the top-down approach... Call me a racist but I just hate punch cards.
Mar 03 2014
parent reply "Chris" <wendlec tcd.ie> writes:
On Monday, 3 March 2014 at 22:50:18 UTC, Frustrated wrote:
 On Monday, 3 March 2014 at 18:46:24 UTC, Chris wrote:
 I think the problem is not that people don't understand 
 templates in the sense that they are abstractions. The 
 question is whether there are loads and loads of use cases for 
 them.
It is irrelevant if there are loads and loads of use cases for them. Just because people don't use something doesn't mean it is useless.
Nobody ever said this. to have to create a function every
 This is a typical use case and always mentioned in tutorials. 
 The question is how many of these "typical" cases one 
 encounters while writing software.
Look at the STL library if you do't believe templates are useful...
 I think another problem with templates is that it is not 
 always clear what is abstracted. The type or the logic? Both? 
 In the above example the logic remains the same and is 
 reproduced by the compiler for each type. Sometimes the logic 
 can be abstracted for which type independence is important. 
 But I'm not sure if that can be called a template in the 
 purest sense. E.g. an algorithm that finds the first instance 
 of something might be different for each type (string, char, 
 int) and the "abstract" implementation has to differentiate 
 internally (if string > else if int > else if ...). But this 
 is no longer a template, or is it?
Both logic and types are abtracted. Even though the template might use the same operator, the compiler must determine which concrete operator to use. The addition between the two abstract objects also requires an abstract operator. The great thing is, because the abstract logic is identical("adding two things") makes the template actually useful. If it wasn't we would have to specialize the template for all the different possible binary combinations and then it would defeat the simplification that abstract is suppose to offer.
Purely philosophical remark: You're talking about the level of how the compiler implements it. The logic (a+b) is not abstracted but the same in every case. How the compiler has to deal with it in every case is irrelevant for the concept of templates, because it's the same as writing: int add(int a, int b) { return a+b;} int add(double a, double b) { return a+b;} etc.
 The the logical process is used when one looks at procedural 
 code and realizes that one can "simplify" it by using oop.

 Templates give you the same power over oop that oop gives over 
 non-oop. But just because templates[oop] are available doesn't 
 mean you have to use it or it is always the best solution.

 I use templates all the time. I create them to simplify some 
 task then put them in a library. For me, templates allow me to 
 streamline things that I couldn't otherwise do. Any time I feel 
 like something is being repeated a lot I automatically think 
 that a templates will help. I hate "copying and pasting" and so 
 I tend to use templates a lot.
I'm starting to do the same thing. But my experience (so far) has been that abstraction goes only so far and a template only covers, say, 2 cases instead of 4 and I have to write 2 separate templates. Granted, in the old days, I would have written a class that handles all four cases, so it saves me some coding. But in may applications, templates are not really necessary. If you write a program that deals with strings, most functions will take a string as an input and return a string (or an array of strings) as an output. This is at least my experience. If code is repeated all over again, you put it into a separate function/method/class/struct anyway. I find myself using ranges quite a lot.
 One of the main uses of templates is compile time type safety. 
 This is necessary with oop because oop allows one to create 
 types at compile time. Hence, the need to be able to make your 
 oop "safe" is a natural step and templates help you accomplish 
 that.

 e.g., Array's of objects vs Array's of a Type. One is much 
 safer, informs the about what your intentions are so it can 
 make better informed decisions.

 e.g., Array!Type allows the Array to determine if the Type 
 supports certain things at **compile time**. Array!Object can't 
 do this at compile time.
Yes, we have useful template constraints (isInputRange etc).
 If you can't see the benefit of Array!Type vs Array!Object then 
 you are beyond help. (this is not to say Array!Object is always 
 useless, but it is the most generic you can get and the 
 compiler can do little to help the situation)

 I'll give you a simple example: One could create an Array type 
 that allows one to traverse the array in a multitude of ways. 
 Suppose the objects stored by the arrays are arrays themselves. 
 If the Array is templated it could easily figure this out and 
 create an iterator that iterates over the sub-array(calling its 
 iterator).

 This way one could easily display a flat list of the array [of 
 arrays [of arrays ...]]. Because the Array type could figure 
 out all this at compile time it would be way more efficient 
 than having to use run-time reflection to determine of the 
 object is an array and if it has the iterator. (it would also 
 be easier to code)

 Basically you have the choice:

 ------------ <- "template" way of thinking (more general than 
 oop)
 -------- <- Oop way of thinking (more general than procedural)
 ----- <- procedural way of thinking... "Old School"
 - <- Punch Cards

 (it's not quite that simple as templates or more of an offshoot 
 of oop)
Maybe that's why it is so hard to see the benefits of templates, because many cases (of abstraction) are already covered by OOP. I like templates, but I'm not sure if they are as useful as D's ranges. Ranges and component programming handle the ubiquitous input>filter>output paradigm present in every program and help to break down the program's logic into digestible chunks, a logic you cannot just copy and paste (but you can reuse the chunks). In cases where you use templates, you can also get away with copy and paste and replace "int" with "double".
 If you are thinking at the template level then you will know 
 when to use templates. If you are thinking at the oop level, 
 you always go for your oop hammer(duh, cause everything looks 
 like an oop nail). If you are thinking at the procedural level 
 then you always try to solve problems in the procedural way.

 I prefer the top-down approach... Call me a racist but I just 
 hate punch cards.
Mar 04 2014
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Mar 04, 2014 at 10:32:52AM +0000, Chris wrote:
[...]
 Maybe that's why it is so hard to see the benefits of templates,
 because many cases (of abstraction) are already covered by OOP. I
 like templates, but I'm not sure if they are as useful as D's
 ranges. Ranges and component programming handle the ubiquitous
 input>filter>output paradigm present in every program and help to
 break down the program's logic into digestible chunks, a logic you
 cannot just copy and paste (but you can reuse the chunks). In cases
 where you use templates, you can also get away with copy and paste
 and replace "int" with "double".
[...] Ranges in D will be nowhere as convenient as they are today without templates. When you write your own components, you basically have to use templates in order to not incur unacceptable overhead (or impose arbitrary limitations on usage -- such as requiring something to be derived from some chosen base class). T -- Never ascribe to malice that which is adequately explained by incompetence. -- Napoleon Bonaparte
Mar 04 2014
parent reply "Chris" <wendlec tcd.ie> writes:
On Tuesday, 4 March 2014 at 15:52:37 UTC, H. S. Teoh wrote:
 On Tue, Mar 04, 2014 at 10:32:52AM +0000, Chris wrote:
 [...]
 Maybe that's why it is so hard to see the benefits of 
 templates,
 because many cases (of abstraction) are already covered by 
 OOP. I
 like templates, but I'm not sure if they are as useful as D's
 ranges. Ranges and component programming handle the ubiquitous
 input>filter>output paradigm present in every program and help 
 to
 break down the program's logic into digestible chunks, a logic 
 you
 cannot just copy and paste (but you can reuse the chunks). In 
 cases
 where you use templates, you can also get away with copy and 
 paste
 and replace "int" with "double".
[...] Ranges in D will be nowhere as convenient as they are today without templates. When you write your own components, you basically have to use templates in order to not incur unacceptable overhead (or impose arbitrary limitations on usage -- such as requiring something to be derived from some chosen base class). T
True, true. The fact that the compiler can check for the right types is great. Btw, the quote you have in this post: Never ascribe to malice that which is adequately explained by incompetence. -- Napoleon Bonaparte I'm surprised that Napoleon would say something like this. Malice is often a characteristic of the incompetent. The only way to get the better of their betters. :-)
Mar 04 2014
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Mar 04, 2014 at 06:19:38PM +0000, Chris wrote:
 On Tuesday, 4 March 2014 at 15:52:37 UTC, H. S. Teoh wrote:
On Tue, Mar 04, 2014 at 10:32:52AM +0000, Chris wrote:
[...]
Maybe that's why it is so hard to see the benefits of templates,
because many cases (of abstraction) are already covered by OOP.  I
like templates, but I'm not sure if they are as useful as D's
ranges. Ranges and component programming handle the ubiquitous
input>filter>output paradigm present in every program and help to
break down the program's logic into digestible chunks, a logic you
cannot just copy and paste (but you can reuse the chunks). In cases
where you use templates, you can also get away with copy and paste
and replace "int" with "double".
[...] Ranges in D will be nowhere as convenient as they are today without templates. When you write your own components, you basically have to use templates in order to not incur unacceptable overhead (or impose arbitrary limitations on usage -- such as requiring something to be derived from some chosen base class). T
True, true. The fact that the compiler can check for the right types is great. Btw, the quote you have in this post: Never ascribe to malice that which is adequately explained by incompetence. -- Napoleon Bonaparte I'm surprised that Napoleon would say something like this. Malice is often a characteristic of the incompetent. The only way to get the better of their betters. :-)
I'm not sure if that attribution is accurate. Nick has pointed out to me that he knows the same quote attributed to someone else, so this may be a case of internet misattribution (I picked up that quote from somewhere online, way back when -- no idea if the source was reliable, y'know, being the internet and everything). T -- I am not young enough to know everything. -- Oscar Wilde
Mar 04 2014
parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 3/4/2014 1:27 PM, H. S. Teoh wrote:
 On Tue, Mar 04, 2014 at 06:19:38PM +0000, Chris wrote:
 Btw, the quote you have in this post:

 Never ascribe to malice that which is adequately explained by
 incompetence. -- Napoleon Bonaparte

 I'm surprised that Napoleon would say something like this. Malice is
 often a characteristic of the incompetent. The only way to get the
 better of their betters. :-)
I'm not sure if that attribution is accurate. Nick has pointed out to me that he knows the same quote attributed to someone else, so this may be a case of internet misattribution (I picked up that quote from somewhere online, way back when -- no idea if the source was reliable, y'know, being the internet and everything).
Hanlon's Razor, a tongue-in-cheek "corollary" (of sorts) to Occam's Razor. I'm a huge believer in Hanlon's Razor, BTW, as well as Occam's Razor which I see as an axiom (for a loose definition of "axiom") that's fundamental in making all of science actually work and separating science from folklore. For all I know, Napoleon may have uttered Hanlon's Razor at some point. I'm sure he's said a lot of things :) If so, he may have been the first.
Mar 04 2014
prev sibling next sibling parent reply Russel Winder <russel winder.org.uk> writes:
On Tue, 2014-03-04 at 10:27 -0800, H. S. Teoh wrote:
 On Tue, Mar 04, 2014 at 06:19:38PM +0000, Chris wrote:
[…]
 True, true. The fact that the compiler can check for the right types
 is great.
 
 Btw, the quote you have in this post:
 
 Never ascribe to malice that which is adequately explained by
 incompetence. -- Napoleon Bonaparte
 
 I'm surprised that Napoleon would say something like this. Malice is
 often a characteristic of the incompetent. The only way to get the
 better of their betters. :-)
I'm not sure if that attribution is accurate. Nick has pointed out to me that he knows the same quote attributed to someone else, so this may be a case of internet misattribution (I picked up that quote from somewhere online, way back when -- no idea if the source was reliable, y'know, being the internet and everything).
I present you the following, which between then give a good account of the whole situation. Sort of. Possibly. http://en.wikipedia.org/wiki/Hanlon's_razor https://www.princeton.edu/~achaney/tmve/wiki100k/docs/Hanlon_s_razor.html http://blog.writch.com/2009/04/hanlons-razor-which-i-knew-as-heinleins-razor.html -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.net 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Mar 04 2014
parent "Chris" <wendlec tcd.ie> writes:
On Tuesday, 4 March 2014 at 19:18:28 UTC, Russel Winder wrote:
 On Tue, 2014-03-04 at 10:27 -0800, H. S. Teoh wrote:
 On Tue, Mar 04, 2014 at 06:19:38PM +0000, Chris wrote:
[…]
 True, true. The fact that the compiler can check for the 
 right types
 is great.
 
 Btw, the quote you have in this post:
 
 Never ascribe to malice that which is adequately explained by
 incompetence. -- Napoleon Bonaparte
 
 I'm surprised that Napoleon would say something like this. 
 Malice is
 often a characteristic of the incompetent. The only way to 
 get the
 better of their betters. :-)
I'm not sure if that attribution is accurate. Nick has pointed out to me that he knows the same quote attributed to someone else, so this may be a case of internet misattribution (I picked up that quote from somewhere online, way back when -- no idea if the source was reliable, y'know, being the internet and everything).
I present you the following, which between then give a good account of the whole situation. Sort of. Possibly. http://en.wikipedia.org/wiki/Hanlon's_razor https://www.princeton.edu/~achaney/tmve/wiki100k/docs/Hanlon_s_razor.html http://blog.writch.com/2009/04/hanlons-razor-which-i-knew-as-heinleins-razor.html
This reminds me of Cipolla's laws of human stupidity. Put this into your search engine: Basic Laws of Human Stupidity, Carlo M. Cipolla Also: https://en.wikipedia.org/wiki/Carlo_M._Cipolla Enjoy!
Mar 04 2014
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Mar 04, 2014 at 07:18:17PM +0000, Russel Winder wrote:
 On Tue, 2014-03-04 at 10:27 -0800, H. S. Teoh wrote:
 On Tue, Mar 04, 2014 at 06:19:38PM +0000, Chris wrote:
[...]
 Btw, the quote you have in this post:
 
 Never ascribe to malice that which is adequately explained by
 incompetence. -- Napoleon Bonaparte
 
 I'm surprised that Napoleon would say something like this. Malice
 is often a characteristic of the incompetent. The only way to get
 the better of their betters. :-)
I'm not sure if that attribution is accurate. Nick has pointed out to me that he knows the same quote attributed to someone else, so this may be a case of internet misattribution (I picked up that quote from somewhere online, way back when -- no idea if the source was reliable, y'know, being the internet and everything).
I present you the following, which between then give a good account of the whole situation. Sort of. Possibly. http://en.wikipedia.org/wiki/Hanlon's_razor https://www.princeton.edu/~achaney/tmve/wiki100k/docs/Hanlon_s_razor.html http://blog.writch.com/2009/04/hanlons-razor-which-i-knew-as-heinleins-razor.html
[...] Whoa. So this is one of those things that nobody knows for sure where it came from? :) My new favorite version of it is (allegedly) Elbert Hubbard's: Genius may have its limitations, but stupidity is not thus handicapped. That's going into my quotes file... :) T -- People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANG
Mar 04 2014
prev sibling parent reply "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:
 I just discovered by trial and error that I could use 'mixin' 
 in Templates (as opposed to Template Mixins), and when you know 
 that it seems likely that you can accomplish lots of stuff you 
 couldn't before.
This was asked about recently. mixin template ... This is the correct way to declare a template to use in mixins, several of us are surprised that you can still mixin a template which wasn't declared in this manner. I've created a bug so an official statement can be made on it: https://d.puremagic.com/issues/show_bug.cgi?id=12298
Mar 04 2014
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Mar 04, 2014 at 07:23:49PM +0000, Jesse Phillips wrote:
 On Sunday, 2 March 2014 at 11:47:39 UTC, Steve Teale wrote:
I just discovered by trial and error that I could use 'mixin' in
Templates (as opposed to Template Mixins), and when you know that
it seems likely that you can accomplish lots of stuff you couldn't
before.
This was asked about recently. mixin template ... This is the correct way to declare a template to use in mixins, several of us are surprised that you can still mixin a template which wasn't declared in this manner. I've created a bug so an official statement can be made on it: https://d.puremagic.com/issues/show_bug.cgi?id=12298
I'm pretty sure that's a bug, since TDPL clearly distinguishes between templates and mixin templates. But if this bug leads to interesting use case, maybe it's a case of an unintentional feature? :-P T -- Knowledge is that area of ignorance that we arrange and classify. -- Ambrose Bierce
Mar 04 2014
prev sibling next sibling parent "Szymon Gatner" <noemail gmail.com> writes:
On Saturday, 1 March 2014 at 18:00:21 UTC, Steve Teale wrote:
 On Friday, 28 February 2014 at 19:06:26 UTC, Dicebot wrote:
 On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 Is this typical - libraries use templates, applications 
 don't, or
 am I just being unimaginative?

 Steve
 Also every time you catch yourself doing any sort of 
 copy-paste, it is quite possible that it can be replaced by 
 mixin / template mixin instead. Application that are built in 
 more declarative way benefit more from such tool set than 
 traditional imperative ones.
In have a couple of case that always require me to find some other instance of it, and then copy/paste, But then I need to edit the pasted code anyway because in any particular case it needs to deal with different command info, so how can mixins help me? I have already dealt with the yada-yada cases by old-fashioned OOP. From the various answers to this question I have concluded that I should not worry about it. If there's a need for a template I think I am already recognizing it. Thanks!all() Steve
This is the best think I've read: https://github.com/PhilippeSigaud/D-templates-tutorial
Mar 02 2014
prev sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 3/1/2014 1:00 PM, Steve Teale wrote:
 I have already dealt
 with the yada-yada cases by old-fashioned OOP.
As I see it, a big part of the benefit of templates is that they can help you avoid a lot of the downsides of OOP: - OO Boilerplate. - Multiple dispatch is ridiculously messy, having to resort to contortions like the visitor pattern. - Upcasting looses compile-time type info. - Decreased opportunity for compiler optimizations, because a single function handles multiple data types at runtime. So the optimizer can't generate optimal code for all the data types used. - Extra indirections at runtime. - Downcasting has a runtime cost. - Poor cache behavior. - Tendency for increased heap activity, which is not cheap at all. - Lumping all data/functionality for a single "object" instance into the same physical chunk of memory causes problems for parallelization. And that's increasingly problematic on modern processors which work best when operating as "streaming-data processors". (See "Entity/Component Systems"[1] - There are good reasons videogame development has mostly switched from OOP to entity/component systems.) Basically, while OOP certainly has benefits, it also has notable flaws that inherently slow down both the programmer and the computer. JVM goes to an enormous amount of trouble to mitigate that natural tendency, but it still has limits. And most languages (like D) can't expect to approach JVM's work on de-slow-ifying OO. The runtime performance issues of OO aren't *always* a problem, but they can easily kill inner-loop/performance-sensitive sections of code. So with OO, you have to give up the generic/polymorphic benefits for any critical sections. Metaprogramming lets you still be generic even in the critical sections. This is demonstrated in sections #1-4 of an article I wrote a little while back[2]. It's a very contrived example, but even I was still surprised just *how* badly the OO version performed. There's also this template primer[3] which might help, but I'm guessing it may be below your ability level. [1] Entity/Component Systems: http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ [2] http://www.semitwist.com/articles/EfficientAndFlexible/MultiplePages/Page1/ [3] https://semitwist.com/articles/article/view/template-primer-in-d
Mar 04 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 - Lumping all data/functionality for a single "object" instance 
 into the same physical chunk of memory causes problems for 
 parallelization. And that's increasingly problematic on modern 
 processors which work best when operating as "streaming-data 
 processors". (See "Entity/Component Systems"[1] - There are 
 good reasons videogame development has mostly switched from OOP 
 to entity/component systems.)
Sometimes OOP is handy, for GUIs and other situations, but if today a more horizontal placement of fields is more efficient when high performance is needed, then perhaps a creative programmer has to find the courage to step out of his/her/hir language constraints to invent a better language. Is it possible to invent a language more fit for this different kind of data layout? Bye, bearophile
Mar 04 2014
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 3/4/2014 7:42 PM, bearophile wrote:
 Nick Sabalausky:

 - Lumping all data/functionality for a single "object" instance into
 the same physical chunk of memory causes problems for parallelization.
 And that's increasingly problematic on modern processors which work
 best when operating as "streaming-data processors". (See
 "Entity/Component Systems"[1] - There are good reasons videogame
 development has mostly switched from OOP to entity/component systems.)
Sometimes OOP is handy, for GUIs and other situations, but if today a more horizontal placement of fields is more efficient when high performance is needed, then perhaps a creative programmer has to find the courage to step out of his/her/hir language constraints to invent a better language. Is it possible to invent a language more fit for this different kind of data layout?
I don't think it's necessary to go as far as creating a new language. An entity-system in a low-level-capable language gives you enough power to control layouts however appropriate, and using them is pretty easy. It seems intimidating at first, but it's really just like a relational DB: You have a unique ident for each "object" (ie, what an OO system would call an instantiated object, but in this case called an "entity"). And then all the data associated with the "object/entity" is stored in various tables/structs/whatever (in this case, called "components") with the entity's unique identifier being the primary key for each table/component. Functionality operates on a particular table/component, or a set of specific tables/components, either on a row-at-a-time basis or as the whole table as an aggregate. Note that this imposes very little, if any, requirements on in-memory layouts, so things can be laid out however desired - possibly even with per-platform topologies thanks to the magic of metaprogramming. In any case, metaprogramming can help abstract away many of the internal memory-layout details. Playing around with the Unity3D editor, and it's tutorial videos, can help grok the usage and modeling power of entities (like any good modern game engine, it uses an entity-based design). Although, FWIW, I'm not convinced Unity3D's design is able to *fully* take advantage of all the potential performance benefits of an entity system (mostly because of its CLR-based scripting and black-box closed-source engine). But, I admit, I have wondered if a language could aid the creation/usage of entity systems with some special language features.
Mar 04 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 But, I admit, I have wondered if a language could aid the 
 creation/usage of entity systems with some special language 
 features.
I have seen that a good way to learn lazyness and purity is to try to write some Haskell code. Then you can use the same ideas in other languages, like D. Similarly I've studied regular expressions in dynamic languages, and now I am able to use them in Java, C#, D, etc. So I've seen that it's good to learn a feature/style in a language that uses it a lot, or even in a language designed around such feature. Because languages shape your mind, and specialized languages train your mind to use few specific features. Later in real-world situations often you can't use such specialized/esoteric/rare language, and you have to use a common language as Java. And sometimes if people use a feature a lot in other languages, eventually it gets ported even to the common languages (like lambdas in Java). So even if you can't or you don't want to use a new language to use entity systems, training your mind a bit thinking in a new language designed for it could help use it in a common language, or could even suggest you few features to add to a more general purpose language as D. Wouter van Oortmerssen shows very well that designing many small specialized languages helps you sharpen your mind and later you apply those ideas to more general situations: http://strlen.com/language-design-overview Bye, bearophile
Mar 04 2014
parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 3/4/2014 9:00 PM, bearophile wrote:
 Nick Sabalausky:

 But, I admit, I have wondered if a language could aid the
 creation/usage of entity systems with some special language features.
I have seen that a good way to learn lazyness and purity is to try to write some Haskell code. Then you can use the same ideas in other languages, like D. Similarly I've studied regular expressions in dynamic languages, and now I am able to use them in Java, C#, D, etc. So I've seen that it's good to learn a feature/style in a language that uses it a lot, or even in a language designed around such feature. Because languages shape your mind, and specialized languages train your mind to use few specific features. Later in real-world situations often you can't use such specialized/esoteric/rare language, and you have to use a common language as Java. And sometimes if people use a feature a lot in other languages, eventually it gets ported even to the common languages (like lambdas in Java). So even if you can't or you don't want to use a new language to use entity systems, training your mind a bit thinking in a new language designed for it could help use it in a common language, or could even suggest you few features to add to a more general purpose language as D. Wouter van Oortmerssen shows very well that designing many small specialized languages helps you sharpen your mind and later you apply those ideas to more general situations: http://strlen.com/language-design-overview
Yea, all good points. I'm reminded of one of my favorite quotes from Joel Spolsky: "I have never met anyone who can do Scheme, Haskell, and C pointers who can't pick up Java in two days, and create better Java code than people with five years of experience in Java, but try explaining that to the average HR drone." - http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
Mar 04 2014
prev sibling next sibling parent "FreeSlave" <freeslave93 gmail.com> writes:
Well, when you're starting to use many templates you may end up 
with separate library.

Templates provide compile-time correctness, concepts (in Boost 
sense), policy-base design (see "Modern C++ Design: Generic 
Programming and Design Patterns Applied" by Andrei Alexandrescu) 
and compile-time choice of the most optimized way to do things. 
Eventually templates are here just to ease programming of 
applications and reduce boilerplate. All these things that we 
expect from libraries and that library's author must take into 
account.

D is multiparadigm language so you should not worry if you don't 
use some of its features. You may ask same question about 
delegates, attributes or user defined exceptions. The answer is 
simple: it all depends on your style, preferences and needs, your 
vision how perfect code should look like.
Feb 28 2014
prev sibling next sibling parent "Meta" <jared771 gmail.com> writes:
On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 All the D aficionados seem to wet their pants over
 meta-programming, but I struggle to find a place to use it.

 IIRC, I used it in a couple of places when I was trying to write
 library stuff for MySQL, but in my current project, I use it 
 only
 once. That's when I want to stuff something onto my undo stack.

 For that I have two template functions - push(T)(MybaseClass* p,
 T t, int ID), and pushC, which is just the same except that it
 checks the top of the stack to see if the ID there is the same 
 as
 what it is wanting to push.

 This has served me very reliably, but I struggle to find other
 places in the whole application where I would benefit from
 templates.

 Is this typical - libraries use templates, applications don't, 
 or
 am I just being unimaginative?

 Steve
It really depends on what you're writing. If you look at Phobos, which is meant to be as general as possible, I'd estimate that about 70% of it is templated, possibly more. I find that general utilities (such as your push function) are pretty much always template, while most program logic isn't. If you find yourself writing mainly program logic with very little need for utility functions, then it shouldn't be surprising that you are not using templates that much. The one exception is when doing stuff that requires a lot of boilerplate; mixins and template mixins are extremely useful for that.
Feb 28 2014
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Feb 28, 2014 at 06:42:57PM +0000, Steve Teale wrote:
 All the D aficionados seem to wet their pants over
 meta-programming, but I struggle to find a place to use it.
 
 IIRC, I used it in a couple of places when I was trying to write
 library stuff for MySQL, but in my current project, I use it only
 once. That's when I want to stuff something onto my undo stack.
 
 For that I have two template functions - push(T)(MybaseClass* p,
 T t, int ID), and pushC, which is just the same except that it
 checks the top of the stack to see if the ID there is the same as
 what it is wanting to push.
 
 This has served me very reliably, but I struggle to find other
 places in the whole application where I would benefit from
 templates.
 
 Is this typical - libraries use templates, applications don't, or
 am I just being unimaginative?
[...] As others have said, it depends on your needs and what you're trying to accomplish. :) If you find that your code contains some functions that are generically applicable, you can turn them into templates. Or leave them as normal functions until another piece of code needs to call it with different parameter types, then turn it into a template. A lot of my code starts out that way and turn into templates once it becomes clear that they are generically applicable. It's also some degree of future-proofing: I work with numerical software, for example, and knowing that one day I might desire to substitute the built-in floating point types with, say, something that can represent quadratic rationals (numbers of the form a+b*√c) exactly, is an indication to me that functions that operate on these quantities should be templated on the number type. But on the other hand, if something doesn't *need* to be a template, then don't use templates. :) It depends on what you're trying to accomplish. Use the right tools for the job. Not every problem is a nail to be hammered; sometimes using a screwdriver for a screw is just what you need. T -- There are two ways to write error-free programs; only the third one works.
Feb 28 2014
prev sibling next sibling parent "Frustrated" <Frustrated nowhere.com> writes:
On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 All the D aficionados seem to wet their pants over
 meta-programming, but I struggle to find a place to use it.

 IIRC, I used it in a couple of places when I was trying to write
 library stuff for MySQL, but in my current project, I use it 
 only
 once. That's when I want to stuff something onto my undo stack.

 For that I have two template functions - push(T)(MybaseClass* p,
 T t, int ID), and pushC, which is just the same except that it
 checks the top of the stack to see if the ID there is the same 
 as
 what it is wanting to push.

 This has served me very reliably, but I struggle to find other
 places in the whole application where I would benefit from
 templates.

 Is this typical - libraries use templates, applications don't, 
 or
 am I just being unimaginative?
Yes. Templates are awesome. I use them when ever I can. They allow you to simplify the tasks. If you check out my thread about dependencies you can see a good example. iGui --> iButton | | |> WindowsGui --> WindowsButton | |> LinuxGui --> LinuxButton When programming to interfaces you lose the ability to use concrete types easily. E.g., WindowsGui can't use a WindowsButton because it has to implement iGui, which uses iButton... even though WindowsButton is an iButton and the only one we want to use with WindowsGui. But as far as WindowsGui is concerned, there is no iButton but just a WindowsButton(Because it doesn't care about being general... and doesn't care about LinuxButton, RogueButton, or whatever). In some sense, iButton was meant to be used with iGui and WindowsButton for WindowsGui... but we can't do this easily in D... well, unless you use a template to generate all the crap code you would normally have to write. So a template(compile time construction) can help do things easier than you could otherwise... and if you do them right they are generic enough to be used in general things. (like anyone could use the template I created to help them with the same type of problem) You are missing the point because the whole reason templates are generally used in libraries is because they are so powerful(you want to reuse them). In the example I give above, the mixin template reduces code bloat and error proneness significantly for large classes and makes you feel like you are writing classes like you would normally write them when not using interface programming. Basically until you start using templates a lot you won't know where to use them in the first place. You just gotta get used to them and then you'll start trying to use them everywhere. (granted, I'm using mixin templates but templates nonetheless)
Feb 28 2014
prev sibling next sibling parent reply "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 Is this typical - libraries use templates, applications don't, 
 or
 am I just being unimaginative?

 Steve
I believe it is typical. However it can also be definition, what is a library? What is an application? Certainly your application uses libraries, and it is very likely a library you need hasn't been written for your application, so you may end up writing libraries. If you write a templated function it is to be used in many places for many things, shouldn't it be in a library? I believe that the majority of an application should be library. I can't claim to achieve this or that the libraries I create are not monolithic, but it is a view that I think helps to simplify the application.
Feb 28 2014
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Mar 01, 2014 at 01:07:04AM +0000, Jesse Phillips wrote:
 On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
Is this typical - libraries use templates, applications don't, or
am I just being unimaginative?

Steve
I believe it is typical. However it can also be definition, what is a library? What is an application? Certainly your application uses libraries, and it is very likely a library you need hasn't been written for your application, so you may end up writing libraries. If you write a templated function it is to be used in many places for many things, shouldn't it be in a library? I believe that the majority of an application should be library. I can't claim to achieve this or that the libraries I create are not monolithic, but it is a view that I think helps to simplify the application.
+1. I find that my code tends to be cleaner and better designed when I write it as though it is going to be a library (even if it doesn't actually end up being a library). It's a good approach to improve the quality of the code I write. T -- If you compete with slaves, you become a slave. -- Norbert Wiener
Feb 28 2014
prev sibling next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
In my experience in D, it comes down to one thing. Do I need to 
handle the type of something and act upon it?

This is shown heavily in dvorm and Cmsed's router/restful 
api/javascript generator.
In these cases I need to create code and have it string mixed in 
based upon a type.

However I'm not aware of many things needing this functionality.
Feb 28 2014
prev sibling next sibling parent "Mike Parker" <aldacron gmail.com> writes:
On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 All the D aficionados seem to wet their pants over
 meta-programming, but I struggle to find a place to use it.

 IIRC, I used it in a couple of places when I was trying to write
 library stuff for MySQL, but in my current project, I use it 
 only
 once. That's when I want to stuff something onto my undo stack.

 For that I have two template functions - push(T)(MybaseClass* p,
 T t, int ID), and pushC, which is just the same except that it
 checks the top of the stack to see if the ID there is the same 
 as
 what it is wanting to push.

 This has served me very reliably, but I struggle to find other
 places in the whole application where I would benefit from
 templates.

 Is this typical - libraries use templates, applications don't, 
 or
 am I just being unimaginative?
I use them for custom containers, configurations and the like, which is the most obvious case -- when multiple types need to be handled and I don't want to implement the same code for each type. With my C and Java background (read, limited experience with templates), it's been hard to recognize other uses. I was ridiculously happy with myself recently when I realized I could make my OpenGL vertex buffer code more flexible by using templates and other compile time constructs to configure different vertex formats, something that was rather non-obvious to me before.
Feb 28 2014
prev sibling parent "Sean Kelly" <sean invisibleduck.org> writes:
On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
 All the D aficionados seem to wet their pants over
 meta-programming, but I struggle to find a place to use it.

 IIRC, I used it in a couple of places when I was trying to write
 library stuff for MySQL, but in my current project, I use it 
 only
 once. That's when I want to stuff something onto my undo stack.

 For that I have two template functions - push(T)(MybaseClass* p,
 T t, int ID), and pushC, which is just the same except that it
 checks the top of the stack to see if the ID there is the same 
 as what it is wanting to push.

 This has served me very reliably, but I struggle to find other
 places in the whole application where I would benefit from
 templates.

 Is this typical - libraries use templates, applications don't, 
 or am I just being unimaginative?
This is certainly my experience with C++ and is why I wrote the chapter on templates in the "Tango with D" book. Personally though, I use templates constantly. For functions, the most common case is to eliminate code duplication where I might normally overload for different parameter types.
Mar 04 2014