March 17, 2012
On Sat, Mar 17, 2012 at 10:15:26PM +0100, Simen Kjærås wrote:
> On Sat, 17 Mar 2012 21:56:14 +0100, novice2 <sorry@noem.ail> wrote:
> 
> >How it come, that we build another abstartion level above strong
> >typed language?
> >Onece we builded high level language above assembler. Are we now
> >building another more high level? Will temlate will become another
> >language used as complete language? Will generic prigramming
> >become mainstream, like high level languages today?
> 
> It seems to me that templates are mostly useful for libraries. In user code this flexibility is rarely as useful. It may however be that this very same argument was put forth when OO was introduced.

I disagree. I use templates all the time, in my own code. It's a great way to factor out common code, so that you avoid code duplication (which often also means bug duplication).

For example, I'm writing a grid-based game, where I have a Board class that stores an array of tiles representing game pieces. For various reasons (not relevant here), I decided I should store the tiles as a linear array, and just overload opIndex() to provide "2D access":

	class Board {
		Tile[] tiles;
		int width, height;

		Tile opIndex(int x, int y) {
			return tile[offsetOf(x,y)];
		}

		private int offsetOf(int x, int y)
		in { assert(x>=0 && x<width && y>=0 && y<height); }
		out(z) { assert(z>=0 && z<tiles.length); }
		body {
			return x + y*width;
		}
	}

Later on, after I've implemented a working game, I decide to make the AI player a bit smarter. For that, I decided to have the AI precompute optimal movement paths by assigning an integer to each tile, and then scanning the board to find optimal paths based on the ints assigned to each tile.

I *could* add an int to Tile and use that, but the problem is, they are only used during the pre-game computation by the AI; the computed paths are stored separately after this computation is done, so the integers are not needed during the actual gameplay. So storing the ints in Tile is a waste of space.

So what I really need is a Board that stores ints instead of Tiles. But the current Board class is already bound to Tile's! What can I do?

Aha! I can make Board a template:

	class Board(T) {
		T[] tiles;
		int width, height;

		T opIndex(int x, int y) { ... }
		...
	}

Then for the actual game board, I'd have:

	Board!Tile gameboard;

And for the AI's precomputed data, I'd have:

	Board!int aidata;

After the AI has found the optimal paths, I can discard aidata and continue using gameboard.

Situations like this arise quite often in my code. So I'd say that templates are definitely not limited to library code. They are generally applicable.


T

-- 
Famous last words: I *think* this will work...
March 17, 2012
On 17-3-2012 21:20, Nick Sabalausky wrote:

> Here's a little templates primer, I hope it helps:

[...]

Part of this primer would serve well as introduction
to Phillipe's tutorial, because it skips the basics.

(I knew the basics, but not everybody does.)

Jos

March 17, 2012
On Sat, Mar 17, 2012 at 09:45:51PM +0100, Gour wrote:
> On Sat, 17 Mar 2012 21:29:18 +0100
> Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> 
> > I had no idea what templates were when I started using D, and I thought I would never need to use them either. But now I use them extensively. They really become a natural tool in programming. They're so nice to use that I never have to reach for the big fat OOP monster, I can just write simple procedural code and use templates when I need some flexibility.
> 
> Thank you for this paragraph. ;)
> 
> I also consider to write procedural/functional code in my project and leave OOP behind, so it's nice to know that templates are the way to go.
[...]

I don't think you can discard OOP entirely. It still has its place IMO. When you need runtime polymorphism, OOP is still the best tool for the job.

But yeah, quite often you don't need full-fledged runtime polymorphism, just a little compile-time flexibility (contrary to what the OO zealots would have you believe). D templates are more than suitable for the job. Using OO for this kind of thing just introduces unnecessary bloat and slow performance.

(Not to mention, D templates can do some stuff that no OO can hope to attain. But it goes both ways. Templates can't do runtime polymorphism either.)


T

-- 
Sometimes the best solution to morale problems is just to fire all of the unhappy people. -- despair.com
March 18, 2012
Wow, popular thread is popular.

Thanks for all the help, everyone.  I haven't read all of it, but I will take the time to sift through everything and see what I can apply.

Response to some of what I did read:
-I didn't conclude that templates are confusing because they confused me.  I concluded templates are confusing because both of the D language reference pages which talk about them have quotes at the top talking about how confusing Templates are.  Reflecting on my (short!) experience trying to learn them, I merely concluded that templates are confusing because nobody really makes an effort to explain them cleanly.  Now, the effort has been made about 22 times(by my count) in this thread alone, so that's a plus!

-While most of my programming professors had a decent idea of what they were doing, the classes themselves left massive, gaping holes in my education that I never even realized were there until I got a job writing Java code.  I don't even particularly LIKE Java.

Could just be that I'm a slow learner.

I messed around with Templates after making that post and learned that they seem to behave similar to Generic types in Java(I am forever finding warnings that a generic type hasn't been type specified in our code.  Sometimes I fix it, sometimes I leave it alone)  I tried rewriting my structs to utilize templates(I currently have separate versions for float and int types) but that did little more than illustrate just how lost I was, so I switched back.  It should be possible in theory, the question is the practice.

Study was further set back by the fact that I suddenly realized none of my operator overloads are working... at all.  It looks like it checks with the language reference page, but I think it's time to write another toy-sized learning program.
March 18, 2012
"H. S. Teoh" <hsteoh@quickfur.ath.cx> wrote in message news:mailman.834.1332023905.4860.digitalmars-d@puremagic.com...
>
> (Not to mention, D templates can do some stuff that no OO can hope to attain. But it goes both ways. Templates can't do runtime polymorphism either.)
>

Combined with compile-time reflection, I'm sure they could be used to create a runtime polymorphism tool, even multiple dispatch. Like I mentioned recently in a seperate thread, you'd just need to use templates/ctfe to automate/genericize this:

void singleDispatch(Object o)
{
    if(auto derived = cast(DerivedClassA)o)
        derived.foo();
    else if(auto derived = cast(DerivedClassB)o)
        derived.foo();
    else if(auto derived = cast(DerivedClassC)o)
        derived.foo();
    //etc...
}

Although I guess *technically* you're still relying on OO polymorphism (in the form of downcasting) to achieve this. OTOH, you could still base it on Variant or Algebraic instead of (or in addition to) Object. Then you'd have built runtime polymorphism out of templates (among other things) without relying on OO.


March 18, 2012
On Sat, Mar 17, 2012 at 08:37:35PM -0400, Nick Sabalausky wrote:
> "H. S. Teoh" <hsteoh@quickfur.ath.cx> wrote in message news:mailman.834.1332023905.4860.digitalmars-d@puremagic.com...
> >
> > (Not to mention, D templates can do some stuff that no OO can hope to attain. But it goes both ways. Templates can't do runtime polymorphism either.)
> >
> 
> Combined with compile-time reflection, I'm sure they could be used to create a runtime polymorphism tool, even multiple dispatch. Like I mentioned recently in a seperate thread, you'd just need to use templates/ctfe to automate/genericize this:
> 
> void singleDispatch(Object o)
> {
>     if(auto derived = cast(DerivedClassA)o)
>         derived.foo();
>     else if(auto derived = cast(DerivedClassB)o)
>         derived.foo();
>     else if(auto derived = cast(DerivedClassC)o)
>         derived.foo();
>     //etc...
> }
> 
> Although I guess *technically* you're still relying on OO polymorphism (in the form of downcasting) to achieve this. OTOH, you could still base it on Variant or Algebraic instead of (or in addition to) Object. Then you'd have built runtime polymorphism out of templates (among other things) without relying on OO.
[...]

But now you're just reimplementing OO in terms of templates. :-) You can do OO in C, too. (In fact, at work some of the C code I deal with are approximations to OO.) That has nothing to do with templates themselves per se.


T

-- 
He who does not appreciate the beauty of language is not worthy to bemoan its flaws.
March 18, 2012
"Entity325" <lonewolf325@gmail.com> wrote in message news:vxadflowsujbbmpnrocg@forum.dlang.org...
>
> -While most of my programming professors had a decent idea of what they were doing, the classes themselves left massive, gaping holes in my education that I never even realized were there until I got a job writing Java code.  I don't even particularly LIKE Java.
>

IMHO, that means you're smart :)

But you touched on an interesting thing about learning and knowledge: It's difficult to know how much is out there that you don't know. After all, if you're unaware of it, then how *can* you know that you're unaware of it? Arguably, one measure of personal progress is how much you suddenly realze there is that you *don't* know and didn't know.

As amateurs, we're opened up to a new world and tend to feel like we know everything about the subject and can do anything with it. Then as we progress we learn how much there really is left to learn. Sort of Zen or Tao, really.

> I messed around with Templates after making that post and learned that they seem to behave similar to Generic types in Java

Definitely. Generic types in language like Java can be thought of as one specific special case of templates. Templates are a good way to do generic types, but then they can *also* do a lot more than just types.


March 18, 2012
"Simen Kjærås" <simen.kjaras@gmail.com> wrote in message news:op.wbb24i010gpyof@biotronic.lan...
> On Sat, 17 Mar 2012 21:20:42 +0100, Nick Sabalausky <a@a.a> wrote:
>
>> I've spent a total of about 6 years in college, always got A's and B's in the CS classes, and yet I'm convinced that programming classes are completely and utterly useless. Most of the instructors themselves barely even know how to code (among many, many other problems). So if you're learning programming at college, then I'm not surprised you've gotten the impression that nobody understands templates: Around universities, they probably don't. (Also, it doesn't help that C++'s templates could be a lot better.)
>>
>> I even had one CS prof, he said that the only language he knew was C. And yet, after seeing his feedback on my code, it became abundantly clear to me that he didn't even understand how strings worked (ie: C's famous null-terminated strings) *in the ONE language he knew*.
>
> You seem to be harping on this a lot.

Sorry. I definitely *do* have a big chip on my shoulder on the matter.


March 18, 2012
"H. S. Teoh" <hsteoh@quickfur.ath.cx> wrote in message news:mailman.839.1332031513.4860.digitalmars-d@puremagic.com...
> On Sat, Mar 17, 2012 at 08:37:35PM -0400, Nick Sabalausky wrote:
>> "H. S. Teoh" <hsteoh@quickfur.ath.cx> wrote in message news:mailman.834.1332023905.4860.digitalmars-d@puremagic.com...
>> >
>> > (Not to mention, D templates can do some stuff that no OO can hope to attain. But it goes both ways. Templates can't do runtime polymorphism either.)
>> >
>>
>> Combined with compile-time reflection, I'm sure they could be used to create a runtime polymorphism tool, even multiple dispatch. Like I mentioned recently in a seperate thread, you'd just need to use templates/ctfe to automate/genericize this:
>>
>> void singleDispatch(Object o)
>> {
>>     if(auto derived = cast(DerivedClassA)o)
>>         derived.foo();
>>     else if(auto derived = cast(DerivedClassB)o)
>>         derived.foo();
>>     else if(auto derived = cast(DerivedClassC)o)
>>         derived.foo();
>>     //etc...
>> }
>>
>> Although I guess *technically* you're still relying on OO polymorphism (in the form of downcasting) to achieve this. OTOH, you could still base it on Variant or Algebraic instead of (or in addition to) Object. Then you'd have built runtime polymorphism out of templates (among other things) without relying on OO.
> [...]
>
> But now you're just reimplementing OO in terms of templates. :-) You can do OO in C, too. (In fact, at work some of the C code I deal with are approximations to OO.) That has nothing to do with templates themselves per se.
>

I'd argue: To view that (particularly if using Variants) as reimplementing OO, is to blur the distinction between OO and polymorphism. OO is such a popular form of polymorphism that we're conditioned to look at polymorphism and say "Oh, that's OO". Really, OO is just one way of doing polymorphism. You define a class. You define a subclass and override its methods. Etc. Other forms of polymorphism exist, such as defining over*loads* and dispatching to them based on the type in a Variant - which, AIUI, is what some non-OO polymorphic languages do behind-the-scenes (though I could be wrong). Uhh, i *think* ML is one such example. Anyway, these other types of polymorphism can easily look like OO because, since they're all just forms of polymorphism, they look like they're just variations on the same fundamental thing. And that's because they are just variations on the same fundamental thing: polymorphism.


March 18, 2012
"novice2" <sorry@noem.ail> wrote in message news:hzbmfpsyzezjwzshxjsp@forum.dlang.org...
> How it come, that we build another abstartion level above strong typed
> language?
> Onece we builded high level language above assembler. Are we now building
> another more high level? Will temlate will become another language used as
> complete language? Will generic prigramming become mainstream, like high
> level languages today?

It's really just another tool in the toolbox. Like OO.

And there's always more abstractions on top of abstractions: High-level langauges are an abstration on top of low-level. Low level programming is an abstration on top of digital hardware. Digital hardware is an abstraction on top of analog hardware. Analog hardware is an abstraction on top of chemistry. Chemistry is an abstration on top of natural observations of interacting with various materials. Observations are an abstraction on top of our perceptions of reality and sensory input.

First we discover useful things to do with one abstraction. Then we make use of that abstraction to the point where it starts to get complex. So we look for patterns in the complexity and use those patterns as the foundation for a new abstraction to make these complicated new things simple. And it starts again. Sending a link to a document across the world is trivial today, but it would be unthinkably complex without the abstractions of high level code, low level code, digital hardware, etc.