Generic code: @autoconst, @autopure, @autonothrow
Tomek Sowiński
just at ask.me
Mon Aug 30 12:10:10 PDT 2010
Dnia 29-08-2010 o 06:57:17 Brad Roberts <braddr at 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
More information about the Digitalmars-d
mailing list