2010/8/30 Andrei Alexandrescu <seewebsiteforem...@erdani.org> > On 8/30/10 14:16 PDT, Tomek Sowiński wrote: > >> Dnia 30-08-2010 o 21:10:10 Tomek Sowiński <j...@ask.me> napisał(a): >> >> How about reduce!fun(range)? It's pure/nothrow when fun is >>> pure/nothrow. Plenty of std.algorithm would benefit. >>> >> >> Eh, nevermind. popFront() must mutate the range so it can't be pure. >> Need to get some sleep... >> > > It can still be nothrow depending on input, which makes a solid point. > Arguments against qualifier/attribute propagation based on sheer semantics > ("it's abs so it must be pure") break badly in the face of higher-order > functions. > > It's pretty clear we need an attribute propagation mechanism if we want > e.g. to make Phobos const-aware.
Could something like this be a possible building block for pure? import std.stdio, std.bigint; /** Test whether expression expr is pure for type Type. */ template isPure(Type, string expr) { enum isPure = isPureImpl!(Type, expr); } bool isPureImpl(Type, string expr)() { mixin("auto pureTester(T)(T a) pure { return " ~ expr ~ ";}"); return is(typeof( pureTester(Type.init) )); } int foo(int i) { return i;} // not pure int bar(int i) pure { return i;}// pure void test(T)(T num) if (isPure!(T, "-1*a")) // test that with "-1*a", "-1*foo(a)" and "-1*bar(a)" { writeln("Yes, pure expr for type " ~ T.stringof); } void main() { test(1); auto b = BigInt("1"); // test(b); // is -1*b a pure expr for BigInts? } test(1) will compile for expression -1*a or just "a" test(BigInt("1")) will not compile with expression -1*a, because it's not pure for BigInts. It will compile with just "a" as constraint expression. I also tried to instantiate test(1) with -1*bar(a) and -1*foo(a) as constraints. It passes for -1*bar(a), because bar is pure, but not with foo(a). Maybe then it's possible to create a pure version of a function if this passes the test. I'm not sure, it's late in there. Also, this could be done also for nothrow. I didn't think it through for const. Philippe