Returning const? -- A potential solution

Tim M a at b.com
Sat Mar 7 21:48:35 PST 2009


On Sun, 08 Mar 2009 17:56:09 +1300, Daniel Keep  
<daniel.keep.lists at gmail.com> wrote:

>
>
> Jason House wrote:
>> The ugly const thread got me thinking about the old problem of  
>> returning an
>> input while preserving const safety.  I have an idea that seems
>> reasonable...
>>
>> In a nutshell, I'm thinking that const(T) should be a base type for T,
>> immutable(T) and return(T).
>
> Wasn't there something like typeof(return) for this?  I do agree that
> something like this needs to be done: I shouldn't have to muck about
> with mixins and/or templates just because I've written a function that
> will work irrespective of const-ness, and thus should work with any
> const-ness on the arguments.
>
>> return(T) is treated in a read-only fashion,
>> just like const(T) and immutable(T). Here are some of the key things I  
>> think
>> this achieves:
>>   * Input arguments are never mutated
>
>> From whose perspective?  This is one of the weird things about
> const-ness; it's meaning depends on your perspective.  :P
>
> I assume you meant "Input arguments are never mutated by the callee."
>
>>   * Use of input parameters in calls to functions as const(T) is 100%  
>> legal.
>
> Well, one would hope so.  Given that this would mean that arguments
> being T, const(T) or immutable(T) would be valid, this seems to be in
> the same boat as:
>
> "Features of water: it's got hydrogen in it!"
>
>>   * Temporary variables can legally be defined and used
>
> I don't get this.  In what context?  I wasn't aware that using const(T)
> in your code prevented you from having temporary variables...
>
>>   * Calling other functions that return return(T) is allowed
>
> I'd bloody well hope so!
>
>>   * No code duplication
>
> THIS right here should be the #1 reason.  Having to create multiple
> versions of a function just to correctly propogate const-ness is a right
> PITA.
>
> Yes, templates, mixins, etc.: I shouldn't HAVE to resort to them.
>
>>   * No code bloat (compiler only needs to generate one version of the  
>> code)
>
> Perhaps it would be worth adding this:
>
> "Compilers may optionally, as a quality of implementation feature,
> generate an overload of the function which specifically handles
> immutable arguments.  This should only be done for optimised builds.
> Any user code which disallows this optimisation may be reported as a
> warning."
>
> Considering that one of the reasons for having transitive immutability
> is to aid in optimisation, it seems a shame to toss it overboard with a
> pair of lead shoes.
>
>>   * Functions can be virtual
>
> Well, they can be virtual now: you just have to manually instantiate the
> function 3 times.
>
>> Let's take a relatively simple example: max
>>
>> return(T) max(return(T) a, return(T) b){ return (a>b)?a:b; }
>>
>> When max is called, the compiler would examine the inputs for a and b to
>> determine what the true type for return(T) is from the callee's
>> perspective...  So a call with T and immutable(T) would use const(T) as  
>> the
>> perceived return type while an argument of T and T would use T as the  
>> return
>> type.
>>
>> At the call site, the compiler would ensure type safety of how the  
>> return
>> type is used.  Within max, the compiler would ensure that the arguments  
>> are
>> either treated as const(T) in function calls but not mixed with with  
>> types
>> T, const(T), or immutable(T)
>
> One would hope the following would work:
>
> static if( isConst!(typeof(a)) )
> {
>     // Slow, safe way
> }
> else
> {
>     // Exploit mutability
> }
>
>> PS: The return(T) notation is an arbitrary one for the purposes of this
>> post.  We need a technical solution before worrying about the color of  
>> the
>> bicycle shed
>
> It should be red, obviously.  :P
>
> On a more serious note, the return(T) syntax worries me because it looks
> like there's a template at play here, but I can't see it.  But as you
> say, we should worry about getting Walter to agree this is needed  
> first.  :)
>
>

What does this mean:

module tconst;

import std.stdio;

invariant(char)[] func()
{
       invariant(char)[] s = "hello";
       return s;
}

void main()
{
       auto s = func();
       s[0] = 'm'; //error
}

I thought we already have returning const/invariant? That code ^ works  
fine for me.





More information about the Digitalmars-d mailing list