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