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