Jonathan M Davis: >The one problem I see is that if the compiler has to determine whether a given >function can be pure and/or nothrow, it's going to potentially have to go >arbitrarily deep into the call hierarchy to figure it out<
This is already done for pure functions, const, immutable, nothrow, etc, all of them are transitive. > Does anyone have some good suggestions on how to solve this issue? I have an enhancement request on it, of course: http://d.puremagic.com/issues/show_bug.cgi?id=5125 There I have suggested a @optional_tag(), the first argument is a compile-time boolean and the second is an attribute/keyword like pure, nothrow, @safe, etc.: @optional_tag(isPure!F, pure) int[] map(F)(F f, int[] data) { int[] res; foreach (x; data) res ~= f(x); return res; } Where isPure is just: import std.traits: FunctionAttribute, functionAttributes; template isPure(F) { enum bool isPure = functionAttributes!(F) & FunctionAttribute.PURE; } The name "optional_tag" may be improved. This solution is not much general, so you may invent something more elegant. Bye, bearophile