www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - templated()

reply bearophile <bearophileHUGS lycos.com> writes:
(I am busy, I am late with some answers, I am sorry, I will catch up)

This paper is "Minimizing Dependencies within Generic Classes for Faster and
Smaller Programs", by Dan Tsafrir, Bjarne Stroustrup and others:
http://www2.research.att.com/~bs/SCARY.pdf

The article shows problems of C++/D template bloat, and a way to avoid some of
it. It talks a bit about D too, in two points. Near the end it shows an idea
for C++-like languages, Figure 21, page 18:

template<typename X, typename Y, typename Z> struct C {
    void f1() utilizes X,Z {
        // only allowed to use X or Z, not Y
    }
    
    void f2() {
        // for backward compatibility, this is
        // equivalent to: void f2() utilizes X,Y,Z
    }
    
    class Inner_t utilizes Y {
        // only allowed to use Y, not X nor Z
    };
};


I have adapted it to a possible syntax for D:

struct C(X, Y, Z) {
    // only allowed to use X or Z, not Y
     templated(X,Z) void f1() {
    }

    // for backward compatibility, this is
    // equivalent to:  templated(X,Y,Z) void f2()
    void f2() {
    }

    // only allowed to use Y, not X nor Z
     templated(Y) static class Inner {
    }
}


The purpose of  templated() is to help the compiler avoid some template bloat.
Here the class Inner is allowed to use just the Y template argument of C, this
means that if you instantiate C in two ways like this:

C!(int, int, float)
C!(float, int, double)

The Y doesn't change, so the compiler instantiates the code of Inner only once.
If you try to use X or Z in Inner it will not compile.

A sufficiently smart compiler is able to remove duplicated functions with no
need of  templated(), in practice an annotation may help reduce compiler work
or compilation time, to produce smaller code. It also helps document a bit of
the semantics of the code, an enforced documentation.

Bye,
bearophile
Jan 11 2011
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I think that hardcoding instructions in user code for how the compiler
should do its optimizations is a bad idea. But that's just me!
Jan 11 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
I've now remembered that I have discussed this a bit in past, I am sorry for
the partially dupe thread:
http://www.digitalmars.com/d/archives/digitalmars/D/Few_ideas_to_reduce_template_bloat_108136.html

Bye,
bearophile
Jan 11 2011
prev sibling next sibling parent Ary Borenszweig <ary esperanto.org.ar> writes:
Can't the compiler see what is used and where?
Jan 11 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Ary Borenszweig:

 Can't the compiler see what is used and where?
In practice: today I think DMD is not able to do it. LDC has a pass to merge equal or very similar functions, but it's experimental and not much tested yet (and on default it's disabled), and it has strong limitations, it works only in few situations. I don't know about GCC, but probably it too has some limitations. A problem: once the template is instantiated the various functions need different to have different pointers. To face this problem LDC leaves a tiny stub for function duplicates. This problem is not present with templated(), because the annotation allows to change the semantics too a little, so those stubs are not needed. Another problem: templated() avoids some template bloat not duplicating the code. The duplicate removal feature of a compiler like LDC is something extra that removes something that has being compiled, etc. So templated() allows for a faster compilation, unless the compiler is smarter and doesn't even generate the duplicated functions. templated() is a contract between programmer and compiler. The programmer states that she doesn't want to use X and Y template arguments in a part of the template, and the compiler enforces this. So it's enforced documentation that allows the program to specify a bit more semantics in an explicit way. Compiler optimizations are something different. Something good: templated() with no arguments allows to have code that is not templated inside a templated struct, class, etc. This allows to create compiled libraries that contain more code. Bye, bearophile
Jan 13 2011