Generic code: @autoconst, @autopure, @autonothrow

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sat Aug 28 20:20:56 PDT 2010


On 08/28/2010 08:29 PM, dsimcha wrote:
> An issue that comes up very frequently when trying to use const, pure or
> nothrow in generic code is lack of knowledge of whether the functions you're
> calling are const/pure/nothrow.  For example:
>
> T abs(T num) pure nothrow {
>      return (num<  0) ? -1 * num : num;
> }
>
> Looks pretty good.  Won't work with BigInt because opBinary!"*" isn't pure and
> can't practically be made pure.  A solution I propose is to allow the
> annotations @autoconst, @autopure and @autonothrow for template functions.
> These would mean "everything I do is const/pure/nothrow as long as all of the
> functions I call are const/pure/nothrow".  As far as I can tell, this would be
> reasonably implementable because the compiler always has the source code to
> template functions, unlike non-template functions.
>
> A pure function would be allowed to call an @autopure function instantiated
> with a type that makes it pure, and similarly for const and nothrow.  Taking
> the address of an instantiation of an @autopure function would return a pure
> function pointer iff the instantiation was pure.  If an @autopure function
> tried to do anything impure other than call an impure function, ideally the
> result would not compile, since the function is falsely asserting that
> everything it does itself is pure.  This is not an absolute requirement, though.
>
> I believe that this would massively simplify correctly using
> const/pure/nothrow in generic code, which currently is near impossible.  Does
> this sound like it could feasibly be implemented and would work well?

Yah, with the growing interest in applying qualifiers at a larger scale 
(and making Phobos a good example of such) this is quite timely. I've 
been mulling myself over a similar proposal.

What I had in mind is a bit more structured - it would allow selecting a 
type or an expression and assessing its constness/purity. That would be 
done just like .sizeof and .stringof work - by defining two more special 
members .constof, .pureof, .nothrowof. For example:

T abs(T num) (-1 * num).pureof (-1 * num).nothrowof {
     return (num < 0) ? -1 * num : num;
}

The @autoxxx stuff arguably makes this example and probably many others 
easier to write. What I fear in the case of @autoxxx is that the 
compiler will be unable to decide cases in which there are cycles of 
@autoxxx.


Andrei


More information about the Digitalmars-d mailing list