Jump to page: 1 26  
Page
Thread overview
Understanding Templates: why can't anybody do it?
Mar 17, 2012
Entity325
Mar 17, 2012
Walter Bright
Mar 17, 2012
Xinok
Mar 17, 2012
novice2
Mar 17, 2012
Paulo Pinto
Mar 17, 2012
Ali Çehreli
Mar 17, 2012
Ali Çehreli
Mar 17, 2012
Max Klyga
Mar 17, 2012
Nick Sabalausky
Mar 17, 2012
novice2
Mar 17, 2012
Simen Kjærås
Mar 17, 2012
H. S. Teoh
Mar 17, 2012
Paulo Pinto
Mar 17, 2012
Simen Kjærås
Mar 17, 2012
Paulo Pinto
Mar 18, 2012
Nick Sabalausky
Mar 17, 2012
Paulo Pinto
Mar 17, 2012
H. S. Teoh
Mar 17, 2012
Simen Kjærås
Mar 18, 2012
Nick Sabalausky
Mar 17, 2012
Jos van Uden
Mar 23, 2012
Nick Sabalausky
Mar 23, 2012
H. S. Teoh
Mar 23, 2012
Nick Sabalausky
Mar 23, 2012
Sean Kelly
Mar 23, 2012
Sean Kelly
Mar 17, 2012
Andrej Mitrovic
Mar 17, 2012
Gour
Mar 17, 2012
H. S. Teoh
Mar 18, 2012
Entity325
Mar 18, 2012
Nick Sabalausky
Mar 18, 2012
Nick Sabalausky
Mar 18, 2012
H. S. Teoh
Mar 18, 2012
Nick Sabalausky
Mar 18, 2012
Gour
Mar 18, 2012
Paulo Pinto
Mar 19, 2012
Gour
The definition of templates in D
Mar 18, 2012
FeepingCreature
Mar 18, 2012
Derek
Mar 18, 2012
Andrej Mitrovic
Mar 18, 2012
Nick Sabalausky
Mar 18, 2012
Derek
Mar 18, 2012
FeepingCreature
Mar 18, 2012
FeepingCreature
Mar 18, 2012
FeepingCreature
Mar 18, 2012
Derek
Mar 18, 2012
Derek
Mar 18, 2012
Dmitry Olshansky
Mar 19, 2012
Artur Skawina
Mar 18, 2012
Derek
Mar 18, 2012
FeepingCreature
Mar 19, 2012
Sean Kelly
Mar 19, 2012
H. S. Teoh
Mar 19, 2012
Philippe Sigaud
Mar 19, 2012
Nick Sabalausky
March 17, 2012
(Sorry if this is the wrong place for this, or if there's already a thread in existence which would be better.  If either of these is the case, simply point me in the right direction, and I'll be on my way.)

My first interaction with Templates was about 5 years ago, in a C++ class at my university.  I immediately thought "A general type?  This would be great for my logger!" and tried to implement them into the small library I had been developing to save time on the class assignments.

Naturally, I didn't understand them, so after a couple of half-hearted attempts, I gave up and went back to doing things the way I had before.  I've avoided Templates since then, because they don't make any sense!

5 years later, enter D.  In the process of trying to teach myself some D, I've found myself with a library of Structs for which the operator overloading features are extremely handy.

Teensy problem here: the documentation on how to use operators makes use of Template types in the examples.

Having developed a bit more analytical skill and tenacity in the intervening years, I resolved to actually figure the mess out this time.  I have come to a conclusion.

The reason nobody understands Templates is that nobody understands them.

That is to say, nobody understands how Templates work is because, as was the case for me, the sum total of explanation we are given on them in programming class is "These are Templates.  They exist.  They look something like this."

Even the (quite thorough) documentation for the D language reference isn't immune to this, if we take a look.  (http://dlang.org/template.html) As you can see, the page more or less starts off with "--And here are some cool things you can do with templates."

Wait, what?  I feel like I've started watching Primer 20 minutes before the end, without anybody telling me what's going on.

Herein, I think, lies the root of the reason why nobody understands Templates.  I think the solution to this problem is not to comfort programming students by saying "Don't worry, nobody understands Templates."  I think it's time we collectively figured out what they are.  That done, we can overhaul the way new programmers learn how to use them.

Who's with me?  Anybody have a short(but COMPLETE!) example of code that makes use of Templates that you actually understand what's going on there?
March 17, 2012
On 3/17/12 12:14 PM, Entity325 wrote:
> Who's with me? Anybody have a short(but COMPLETE!) example of code that
> makes use of Templates that you actually understand what's going on there?

You're on to something here. Then, as usual, from idea to realization there are quite a few steps.

I took a complementary approach in TDPL: there's no chapter on templates at all. Templates are naturally interwoven with whatever topic is at hand, wherever they're useful. I hoped people would learn templates without even knowing it.


Andrei
March 17, 2012
On 3/17/2012 10:55 AM, Andrei Alexandrescu wrote:
> On 3/17/12 12:14 PM, Entity325 wrote:
>> Who's with me? Anybody have a short(but COMPLETE!) example of code that
>> makes use of Templates that you actually understand what's going on there?
>
> You're on to something here. Then, as usual, from idea to realization there are
> quite a few steps.
>
> I took a complementary approach in TDPL: there's no chapter on templates at all.
> Templates are naturally interwoven with whatever topic is at hand, wherever
> they're useful. I hoped people would learn templates without even knowing it.

Sans value parameters:

 int foo() {
    return 3;
 }

With value parameters:

  int foo(int i) {
    return i;
  }

Sans type parameters:

 struct S {
   int i;
 }

With type parameters:

 struct S(T) {
   T i;
 }

i.e. templates are type parameters.
March 17, 2012
On Saturday, 17 March 2012 at 18:16:31 UTC, Walter Bright wrote:
> i.e. templates are type parameters.

Maybe in C++. In C++, templates are attached to a class or function, where as in D, they're an independent construct. The way I think of it, templates are a tool for building static code from a set of parameters. String mixins are a similar tool which are more powerful but less elegant.

Programmers will use templates for unintended purposes, but that doesn't change what they are. You can use full closures to store references to variables, but that doesn't make functions reference types.
March 17, 2012
Maybe you should first try to learn some concepts about generic programming

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

You will see this is nothing specific to C++ or D, and almost
all modern languages do have some form of genericity.

If you still cannot understand them, you cold try to explain why
you have difficulties understanding this concept, and we could
try to explain them to you. Even improve D's documentation.

--
Paulo

Am 17.03.2012 18:14, schrieb Entity325:
> (Sorry if this is the wrong place for this, or if there's already a
> thread in existence which would be better. If either of these is the
> case, simply point me in the right direction, and I'll be on my way.)
>
> My first interaction with Templates was about 5 years ago, in a C++
> class at my university. I immediately thought "A general type? This
> would be great for my logger!" and tried to implement them into the
> small library I had been developing to save time on the class assignments.
>
> Naturally, I didn't understand them, so after a couple of half-hearted
> attempts, I gave up and went back to doing things the way I had before.
> I've avoided Templates since then, because they don't make any sense!
>
> 5 years later, enter D. In the process of trying to teach myself some D,
> I've found myself with a library of Structs for which the operator
> overloading features are extremely handy.
>
> Teensy problem here: the documentation on how to use operators makes use
> of Template types in the examples.
>
> Having developed a bit more analytical skill and tenacity in the
> intervening years, I resolved to actually figure the mess out this time.
> I have come to a conclusion.
>
> The reason nobody understands Templates is that nobody understands them.
>
> That is to say, nobody understands how Templates work is because, as was
> the case for me, the sum total of explanation we are given on them in
> programming class is "These are Templates. They exist. They look
> something like this."
>
> Even the (quite thorough) documentation for the D language reference
> isn't immune to this, if we take a look.
> (http://dlang.org/template.html) As you can see, the page more or less
> starts off with "--And here are some cool things you can do with
> templates."
>
> Wait, what? I feel like I've started watching Primer 20 minutes before
> the end, without anybody telling me what's going on.
>
> Herein, I think, lies the root of the reason why nobody understands
> Templates. I think the solution to this problem is not to comfort
> programming students by saying "Don't worry, nobody understands
> Templates." I think it's time we collectively figured out what they are.
> That done, we can overhaul the way new programmers learn how to use them.
>
> Who's with me? Anybody have a short(but COMPLETE!) example of code that
> makes use of Templates that you actually understand what's going on there?

March 17, 2012
On 03/17/2012 10:14 AM, Entity325 wrote:

> Who's with me? Anybody have a short(but COMPLETE!) example of code that
> makes use of Templates that you actually understand what's going on there?

The "Templates" chapter of "Programming in D" is supposed to be a gentle introduction to templates:

  http://ddili.org/ders/d.en/templates.html

The book have supposed to build up enough base in the previous chapters to make the topic easy to follow but some of the previous chapters have not been translated to English yet. There is a second templates chapter later in the book that covers to-me more advanced features, which also has not been translated yet.

Please provide feedback. :)

The chapter also contains a link to Philippe Sigaud's "D Templates: A Tutorial".

Ali

March 17, 2012
On 03/17/2012 12:57 PM, Ali Çehreli wrote:

> http://ddili.org/ders/d.en/templates.html

[...]

> The chapter also contains a link to Philippe Sigaud's "D Templates: A
> Tutorial".

Sorry, I did not intend to leave the link to that document out:


https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/dtemplates.pdf

Ali
March 17, 2012
On 2012-03-17 20:14:47 +0300, Entity325 said:
> Who's with me?  Anybody have a short(but COMPLETE!) example of code that makes use of Templates that you actually understand what's going on there?

Philippe Sigaud made a very good tutorial on templates in D - https://github.com/PhilippeSigaud/D-templates-tutorial/raw/master/dtemplates.pdf 


March 17, 2012
"Entity325" <lonewolf325@gmail.com> wrote in message news:pgzkvphadihglayfulij@forum.dlang.org...
>
> That is to say, nobody understands how Templates work is because, as was the case for me, the sum total of explanation we are given on them in programming class is "These are Templates.  They exist.  They look something like this."
>

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*.

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

A template is just clean way of generating code instead of manually copy-pasting a bunch of times (which would end up being a maintenance nightmare).

Suppose you have this:

    int add(int a, int b)
    {
        return a + b;
    }

Call it, of course, like this:

    add(7, 42);

And then you want another version that does it with doubles:

    double add(double a, double b)
    {
        return a + b;
    }

Called, of course, like this:

    add(3.14, 5.73);

Now you've got two copies that are exactly the same thing, just with one little thing changed. If you need top modify one, you'll have to remember to modify the other too. And god help you if it's a really big function and you accidentally make a mistake copying it. It just gets to be a big problem. It violates what we call DRY: "Don't Repeat Yourself".

Let's step back into first grade for a minute: Have you ever drawn or painted with stencils? You make one design, once, by cutting it out of paper. Then you can easily draw and re-draw the same design with different colors: Just place the stencil on a new piece of paper, choose a color, color it, lift the stencil, and there's another copy of your design, but in whatever different color you wanted.

Templates are stencils for code. Heck, even outside of code this is true too. "template" is just another word for "stencil".

So here's how you make an "add() function" stencil. Just "punch out" what you want to change, by making it a template parameter:

    // Make a "stencil"
    template myTemplate(T)
    {
        // This is what's in the "stencil"
        T add(T a, T b)
        {
            return a + b;
        }
    }

Notice how the add() function is exactly the same as before, but the "int"s were changed to "T" (for "Type").

Let's stamp down some "add()" prints:

    // The dot in between is because "add" is *inside* the template
"myTemplate"
    myTemplate!(int).add(7, 42);
    myTemplate!(double).add(3.14, 5.73);

Notice how that's exactly the same as before, but I have that "myTemplate!(int)", and another with "float". The compiler turns that into:

    int add(int a, int b)
    {
        return a + b;
    }
    add(7, 42);

    double add(double a, double b)
    {
        return a + b;
    }
    add(3.14, 5.73);

Suppose now we also want to be able to use add() for ulong and BigInt. Instead of manually copying the function and changing the type, we can just let the *compiler* copy the function and change the type:

    myTemplate!(ulong).add(7, 42);
    myTemplate!(BigInt).add(BigInt(7), BigInt(42));

The compiler, of course, automatically generates:

    ulong add(ulong a, ulong b)
    {
        return a + b;
    }

    BigInt add(BigInt a, BigInt b)
    {
        return a + b;
    }

And then calls them:

    add(7, 42);
    add(BigInt(7), BigInt(42));

You can also add more stuff to the template:

    // A bigger "stencil"
    template myTemplate(T)
    {
        T add(T a, T b)
        {
            return a + b;
        }

        T mult(T a, T b)
        {
            return a * b;
        }
    }

So now the compiler will turn this:

    myTemplate!(int)
    myTemplate!(double)

Into this:

    int add(int a, int b)
    {
        return a + b;
    }

    int mult(int a, int b)
    {
        return a * b;
    }

    double add(double a, double b)
    {
        return a + b;
    }

    double mult(double a, double b)
    {
        return a * b;
    }

And you can use them like this:

    myTemplate!(int).add(7, 42);
    myTemplate!(double).add(3.14, 5.73);

    myTemplate!(int).mult(7, 42);
    myTemplate!(double).mult(3.14, 5.73);

You can put other things inside the template, too, like structs and classes, or even variables:

    template anotherTemplate(T, int initialValue)
    {
        struct Foo
        {
            T value;
            int someInt = initialValue;
        }

        T[] myArray;
    }

    // Use the array:
    anotherTemplate!(string, 5).myArray = ["abc", "def", "g"];

    // Declare a variable "myFoo" of type "Foo":
    //     Foo's "value" should be a string
    //     And Foo's "someInt" should start out as 5
    anotherTemplate!(string, 5).Foo myFoo;
    if(myFoo.someInt == 5)
        myFoo.value = "Hello";

D has some convenient tricks though:

Using that "myTemplate" and "anotherTemplate" all over is a bit of a bother. Why should we have to? D has a shortcut for making and using templates:

    T add(T)(T a, T b)
    {
        return a + b;
    }

That's nothing more than a convenient shortcut for:

    template add(T)
    {
        T add(T a, T b)
        {
            return a + b;
        }
    }

Or the struct:

    struct Foo(T, int initialValue)
    {
        T value;
        int someInt = initialValue;
    }

Which is a convenient shortcut for:

    template Foo(T, int initialValue)
    {
        struct Foo
        {
            T value;
            int someInt = initialValue;
        }
    }

The same trick doesn't work for variables like myArray though, you'll have to manually write them as:

    template myArray(T)
    {
        T[] myArray;
    }

Here's another nice trick: Since the name of the template and the "thing" inside the template is the same, you don't have to repeat them. All you have to write is:

    add!int(7, 42);
    add!double(3.14, 5.73);
    add!BigInt(BigInt(7), BigInt(42));

    mult!int(7, 42);
    mult!double(3.14, 5.73);
    mult!BigInt(BigInt(7), BigInt(42));

    myArray!string = ["abc", "def", "g"];
    myArray!int = [1, 2, 3];
    myArray!double = [1.5, 2.70, 3.14];

    Foo!(string, 5) myFoo;
    if(myFoo.someInt == 5)
        myFoo.value = "Hello";

    Foo!(float, 1) bar;
    if(bar.someInt == 1)
        bar.value = 3.14;

And there's yet one more convenience: A special thing D has called IFTI: Implicit Function Template Instantiation. Yes, it sounds very intimidating, but it's really very easy. D lets you call the functions above like this:

    add(7, 42);
    add(3.14, 5.73);
    add(BigInt(7), BigInt(42));

    mult(7, 42);
    mult(3.14, 5.73);
    mult(BigInt(7), BigInt(42));

Look ma! No types!

D already knows that 7 and 43 are int, so it automatically uses the "add!int" version.

D already knows that 3.14 and 5.73 are double, so it automatically uses the "add!double" version.

D already knows that BigInt(7) and BigInt(42) are BigInt, so it automatically uses the "add!BigInt" version.

So, we've started with this copy-paste mess:

    int add(int a, int b)
    {
        return a + b;
    }

    double add(double a, double b)
    {
        return a + b;
    }

    add(7, 42);
    add(3.14, 5.73);
    add(BigInt(7), BigInt(42)); // ERROR! You didn't write a BigInt version!

And turned it into this:

    T add(T)(T a, T b)
    {
        return a + b;
    }

    add(7, 42);
    add(3.14, 5.73);
    add(BigInt(7), BigInt(42));
    add( /+ anything else! +/ );

Which automatically stamps out any "add()" function you need, when you need it. And we can do the same for structs, classes and variables.


March 17, 2012
On 3/17/12, Entity325 <lonewolf325@gmail.com> wrote:
> Who's with me?  Anybody have a short(but COMPLETE!) example of code that makes use of Templates that you actually understand what's going on there?

I wrote this a long time ago when I was just figuring out what templates were about (it's not a general-purpose template tutorial but just an explanation of a Phobos templated function that someone was curious about): http://prowiki.org/wiki4d/wiki.cgi?D__Tutorial/D2Templates

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.

In the meantime people have written some pretty good tutorials, like Ali Çehreli's chapter on templates, and recently Philippe Sigaud's D Template book. Those should be good resources on templates.
« First   ‹ Prev
1 2 3 4 5 6