Conditional purity

bearophile bearophileHUGS at lycos.com
Sun Jul 25 06:39:19 PDT 2010


Simen kjaeraas:
> This is fairly simple currently:
> 
> template map( alias fn ) { // blah blah blah, whatever is necessary here
>      static if ( isPure!fn ) {
>          pure map( Range )( Range r ) { ... }
>      } else {
>          auto map( Range )( Range r ) { ... }
>      }
> }

Do you mean code like this (this doesn't work yet)?

import std.traits: functionAttributes, FunctionAttribute, isCallable;
import std.stdio: writeln;

pure int sqr(int x) { return x * x; }

int tot = 2;
int adder(int x) { return x + tot; } // not pure

template map(alias fn) {
     static if (isPure!fn) {
         pure int[] map(int[] array) {
            int[] result = new int[array.length];
            foreach (i, item; array)
                result[i] = func(item);
            return result;
        }
    } else {
        int[] map(int[] array) {
            int[] result = new int[array.length];
            foreach (i, item; array)
                result[i] = func(item);
            return result;
        }
    }
}

template isPure(F) if (isCallable!(F)) {
    enum bool isPure = functionAttributes!(F) & FunctionAttribute.PURE;
}

void main() {
    int[] arr1 = [1, 2, 3, 4, 5];
    writeln(arr1);

    int[] arr2 = map!(&sqr)(arr1);
    writeln(arr2);

    int[] arr3 = map!(&adder)(arr1);
    writeln(arr3);

    //writeln(isPure!(typeof(&map!(typeof(&sqr)))));
    //writeln(isPure!(typeof(&map!(typeof(&adder)))));
}

I suggest all people in all D newsgroups, to write code that runs, not uncompilable snippets. All errors in the last Walter's talk can be avoided in few minutes running the code. In Python newsgroups 90% of the code snippets are run before they are shown to people.


> Of course, this leads to code duplication, which is unwanted.

You can probably remove the duplication using a mixin but this makes things worse :-)


> In cases
> like this, I long for some features of the C preprocessor, which would
> be able to insert any kind of code wherever it wants.

It's much better to look for more clean solutions.


> This feature request, and Steve's problems with final (in
> std.pattern..mixin temptes..std.concurrency), makes me think there
> should be some way to specify all (or at least most) such conditionally.
> There seems to be a real need for it.

A silly idea to add or not add an attribute:
import std.traits: IF = Select;
IF!(isPure!TF, @pure, @nothing) int[] map(TF)(TF func, int[] array) {...}

Bye,
bearophile


More information about the Digitalmars-d mailing list