www.digitalmars.com         C & C++   DMDScript  

D - expression templates?

reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Hi there,

has anybody investigated whether the method of "expression templates", as
used in C++ high-performance numeric libraries, can be applied in D? This
method really squeezes out the last grain from C++ templates and is, as of
yet, the only known method to combine maximum performance (on par with
handoptimized fortran77 code or HPF) without sacrificing the expressiveness
of object oriented programming.

In C++, going to the limits of the template mechanism has the drawback of
creating excessive compile-time and absolutely unreadable compiler-errors.
Maybe, the template mechanism of D (with type constrained type parameters,
etc.) will help to overcome these problems?

I have serious doubt, that the current template mechanism has the necessary
flexibility, but maybe, it only needs a few extensions? In any case: this
would be the ultimate test for the power of D templates...

Ciao,
Nobbi
Apr 21 2004
parent reply "Walter" <walter digitalmars.com> writes:
There's no need for expression templates in D, because D supports function
literals. Function literals are a far superior method of supplying arbitrary
code as an argument.
Apr 21 2004
parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Walter wrote:

 There's no need for expression templates in D, because D supports function
 literals. Function literals are a far superior method of supplying
 arbitrary code as an argument.
True, that might actually serve my purpose. The only thing I'm missing there is the possibility to bind arguments when defining function pointers or delegates. Something like (with some invented syntax for unnamed argument placeholders): ---------------- int myadd(int a,int b) { return a + b; }; main() { int a = 2; int delegate(int) myadd2 = myadd(a,int _); assert(myadd2(3) == 5); }; ---------------- This would give you the full lambda-calculus of functional languages, and even more, since you cannot only bind the first argument but arbitrary ones. Be aware that literal functions do not solve this problem, because within a literal function you cannot capture the value of "a" at the time of creation of the closure. Actually, this would even be the connection between functions and delegates. If you view "this" just as one special function argument, you would only need a way to bind not only "this" but any argument of the function. Furthermore, the above syntax (or something similar) would also solve the problem of pointers to overloaded functions: ---------------- void func_a(void function(int) arg) { ... }; void func_a(void function(float) arg) { ... }; void func_b(int) { ... }; void func_b(float) { ... }; func_a(func_b); // ambiguous: what should be called? func_a(func_b(int _)); // clear: the typed placeholder solves the problem ---------------- I'm not sure about the syntax for the placeholder, but the concept certainly is helpful. (Actually, I stole it from the Sather language.)
Apr 22 2004
parent reply Ben Hinkle <bhinkle4 juno.com> writes:
On Thu, 22 Apr 2004 10:24:10 +0200, Norbert Nemec
<Norbert.Nemec gmx.de> wrote:

Walter wrote:

 There's no need for expression templates in D, because D supports function
 literals. Function literals are a far superior method of supplying
 arbitrary code as an argument.
True, that might actually serve my purpose. The only thing I'm missing there is the possibility to bind arguments when defining function pointers or delegates. Something like (with some invented syntax for unnamed argument placeholders): ---------------- int myadd(int a,int b) { return a + b; }; main() { int a = 2; int delegate(int) myadd2 = myadd(a,int _); assert(myadd2(3) == 5); }; ----------------
A nested function could help int main() { int a = 2; int myadd2(int x){ return myadd(a,x); } assert(myadd2(3) == 5); return 0; } The number of characters typed is pretty much the same. If you were looking for something like assert(myadd(a,_)(3) == 5) then that would need a language change. Currently it would look like int main() { int a = 2; assert((delegate int(int y){return myadd(a,y);})(3) == 5); return 0; }
Apr 22 2004
parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Ben Hinkle wrote:
 A nested function could help
Not really: ------------------- int main() { int a = 2; int myadd2(int x){ return myadd(a,x); } a = 3; assert(myadd2(3) == 6); // since the value of a is // evaluated at calltime return 0; } ------------------- Parameter binding, on the other hand would give the desired behaviour: ------------------- int main() { int a = 2; int delegate(int) myadd2 = myadd(a,int _); a = 3; assert(myadd2(3) == 5); // now, the value of a was evaluated at the time of binding // the parameter. Of course, it somehow has to be stored inside the // delegate. return 0; } ------------------- One way of emulating this behavior would be to create an object holding the delegate and any bound parameter value. But this means quite some overhead.
Apr 22 2004
parent reply "Walter" <walter digitalmars.com> writes:
I think delegates already do what you are asking. The delegate contains a
function pointer plus a pointer to the enclosing stack frame.

"Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message
news:c68hrr$28o4$1 digitaldaemon.com...
 Ben Hinkle wrote:
 A nested function could help
Not really: ------------------- int main() { int a = 2; int myadd2(int x){ return myadd(a,x); } a = 3; assert(myadd2(3) == 6); // since the value of a is // evaluated at calltime return 0; } ------------------- Parameter binding, on the other hand would give the desired behaviour: ------------------- int main() { int a = 2; int delegate(int) myadd2 = myadd(a,int _); a = 3; assert(myadd2(3) == 5); // now, the value of a was evaluated at the time of binding // the parameter. Of course, it somehow has to be stored inside
the
         // delegate.

         return 0;
 }
 -------------------

 One way of emulating this behavior would be to create an object holding
the
 delegate and any bound parameter value. But this means quite some
overhead.
Apr 22 2004
parent Norbert Nemec <Norbert.Nemec gmx.de> writes:
Indeed, delegates go most of the way there. (I could simply declare a
dedicated local variable a_myadd like here:

-------------------
int
main() {
        int a = 2;

        int a_myadd = a;
        int delegate(int myadd2 = int delegate(int x){ return myadd(a,x); }
        a = 3;
        assert(myadd2(3) == 5); // now, it works correctly
                                // evaluated at calltime
        return 0;
}
-------------------

Anyway the strong deficiency here is, that delegates pointing to a
stackframe cannot be used as return value. My idea would be to simply
extend the concept of object-delegates so that they can not only carry
around their own "this" pointer but other bound arguments as well.

This straightforward generalization of the concept of delegates would give
you full fledged lambda calculus, and would also show the way of unifying
function pointers and delegates.

Of course, a way around this is, to pack up the bound arguments and the
function pointer into an object with the appropriate () operator and return
that. Anyway, that seems like some overhead that I would really like to
avoid.
Apr 22 2004