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