Const, invariant, strings and "constant data need never be copied"

Nathan Reed nathaniel.reed at gmail.com
Fri Nov 2 15:32:28 PDT 2007


Stewart Gordon wrote:
> Let's first look at string manipulation functions such as those in 
> std.string.  These merely look at a passed-in string and return 
> something - they don't keep the string for later.  They therefore need 
> only a read-only view of a string - they don't need to know that the 
> string is never going to change.  Declaring these with invariant 
> parameters therefore means that it is often necessary to .idup a string 
> just to pass it to one of these functions.  Moreover, if a piece of code 
> manipulates strings with a mixture of direct modification and calls to 
> std.string functions, it necessitates quite a bit of copying of strings.

As I've remarked in another thread, it makes absolutely no sense to me 
to use invariant for the library string functions, for exactly this 
reason.  They used to be const, which enables them to work on any kind 
of string the user might want to call them on (mutable, const, or 
invariant).

> 1. A property .invariant, which just returns the reference as an 
> invariant if it's already invariant, otherwise does the same as .idup.  
> For this to work, the runtime would have to keep a record of whether 
> each piece of allocated memory is invariant, which would interfere with 
> the current ability to cast invariance in or out - but at what cost?

Actually, this wouldn't need to have any runtime consequences, as the 
invariantness-or-not of a thing is part of its static typing, so could 
be determined at compile time.  Of course, something can be invariant 
even if it's not typed as invariant (and undecidably so), but do we 
really need to worry about that?  The .invariant property could simply 
return the array if the array is typed as invariant, and return .idup 
otherwise.

> 3. Some concept of const-transparent functions.  One approach would be 
> to enable a type modifier (or the lack thereof) to be used as a template 
> parameter, with something like
> ----------
> T(char)[] doSomethingWith(typemod T)(T(char)[] param) {
>    ...
> }

A proposal for doing something very much like this is already planned 
for D 2.0 (it's in the WalterAndrei.pdf from the D conference a couple 
months back).  It's called the 'return' storage class, which would make 
the return value of a function take on the same constness or 
invariantness as a parameter:

const(char)[] doSomethingWith(return const (char)[] param) {
     ...
}

What this does is makes the constness of the return value the same as 
the constness of the argument passed to 'param', each time the function 
is called.  You can do something similar with templates already, but you 
  can't make template functions virtual.  The function is type-checked 
with the declared types for the parameter and return (in this case, 
const(char)[]).

Thanks,
Nathan Reed



More information about the Digitalmars-d mailing list