We need a way to make functions pure and/or nothrow based on the

Jonathan M Davis jmdavisProg at gmx.com
Sun Nov 14 16:16:28 PST 2010


On Sunday 14 November 2010 04:26:56 bearophile wrote:
> 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.

@optional_tag as you suggest it does not deal with the same issue that I'm 
trying to address - though it is quite similar. My problem is when you have a 
function within a template where purity and nothrowability the functions called 
within that function depend on some or all of the template's parameters. So, 
checking the purity of a single function isn't going to do it (which appears to 
be what your @optional_tag is doing). Instead, you need a way to tell the 
compiler that if every function call within a function is pure, then mark it is 
pure. If no function call within a function is nothrow, then mark it as nothrow. 
So, @optional(pure) or @optional(nothrow) makes more sense.

The more I look at it, the more it looks feasible too, because in this case, the 
concern is templates. All of the functions in question or inside of templates 
trying to be instantiated. If a function call isn't a function within a 
template, then you already know whether it is pure or nothrow. If it's within a 
template, then you'll know as soon as its instantiated (even if it has to check 
other functions within templates that it calls), because any template functions 
that it uses have to be instantiated before it can be instantiated anyway.

Your issue with map is similar, and it could probably be dealt with as part of 
my suggestion, but it's more narrow than what I'm trying to address.

- Jonathan M Davis


More information about the Digitalmars-d mailing list