Dnia 29-08-2010 o 06:57:17 Brad Roberts <bra...@puremagic.com> napisał(a):
On 8/28/2010 6: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?
This really feels like a work-around rather than addressing the
underlying
problem. These annotations are defining the contract for the function.
The
fact that it's generic just means it's being flexible with the types,
but that
flexibility shouldn't extend to allowing the contract to be violated.
Abs _should_ be pure. If the type being passed to it is incapable
performing
the algorithm purely, then the type isn't valid to be used with abs.
Trying to say that abs should be pure sometimes and not others.. why
bother
having the pure requirement at all?
Maybe it's a bad example, but let's not loose site of the reason pure
exists.
It's not just for the side effects, it's for the contract it defines as
well.
How about reduce!fun(range)? It's pure/nothrow when fun is pure/nothrow.
Plenty of std.algorithm would benefit.
BTW, small suggestion: @autopure -> auto(pure)
Tomek