Returning const? -- A potential solution

Daniel Keep daniel.keep.lists at gmail.com
Sat Mar 7 20:56:09 PST 2009



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.  :)





More information about the Digitalmars-d mailing list