Nesting in pure functions

bearophile bearophileHUGS at lycos.com
Mon Apr 6 01:50:31 PDT 2009


This post was originally meant for digitalmars.D.learn, but maybe it can interest more people here.

Now that the D1/D2 zips have a better internal structure and don't require DMC anymore I am more free to use D2 more, so I have tried to understand how the optimization of pure functions works.

So I have written this toy program that computes:
((x*x)+(x*x)) + ((x*x)+(x*x))


import std.c.stdio: printf;
import std.conv: toInt;

pure int double_sqr(int x) {
    int y, z;
    void do_sqr() { y *= y; }
    y = x;
    do_sqr();
    z += y;
    y = x;
    do_sqr();
    z += y;
    return z;
}

void main(string[] args) {
    int x = args.length == 2 ? toInt(args[1]) : 10;
    int y = double_sqr(x) + double_sqr(x);
    printf("4 * x * x = %d\n", y);
}

double_sqr() is a pure function. do_sqr() isn't a pure function, but it has no side effects outside double_sqr(), so double_sqr() is globally pure still. But the compiler (dmd v2.027) doesn't accept it (notice the strange blank line in the middle):

pure_test3.d(...): Error: pure function 'double_sqr' cannot call impure function 'do_sqr'

pure_test3.d(...): Error: pure function 'double_sqr' cannot call impure function 'do_sqr'

So I have tried to simplify the life of the compiler, changing do_sqr() to sqr() that is something simpler and pure:

pure int double_sqr(int x) {
    int sqr(int y) { return y * y; }
    return sqr(x) + sqr(x);
}

But that doesn't work still:

pure_test3.d(...): Error: pure function 'double_sqr' cannot call impure function 'sqr'

So I've added a pure statement to sqr() too, to state its status:

pure int double_sqr(int x) {
    pure int sqr(int y) { return y * y; }
    return sqr(x) + sqr(x);
}

But it's not acceptable still:

pure_test3.d(...): found 'pure' instead of statement
pure_test3.d(...): Declaration expected, not 'return'
pure_test3.d(...): unrecognized declaration

The good thing of pure functions in D is that they are supposed to allow you to do impure things inside them, as long as you keep the whole function pure. But it seems nested functions can't be used yet inside pure functions. Is this something that can be improved/changed in future?

Bye,
bearophile



More information about the Digitalmars-d mailing list