Extended Type Design: further examples
Andrei Alexandrescu (See Website For Email)
SeeWebsiteForEmail at erdani.org
Mon Mar 19 16:20:04 PDT 2007
Derek Parnell wrote:
> I wish it wasn't so hard to get a simple straight answer from the experts.
It's not like anybody tries to obfuscate their writing.
> So far I think /The W&A Show/ is saying that 'const' and 'invariant' only
> apply to reference data types (objects, variable-length arrays, and
> pointers) and structs. They do not apply *in any way, shape or form* to any
> other data type.
>
> const char[] s; // ok
> const char c; // meaningless, the 'const' is ignored.
> const classFoo f; // okay
> const double* b; // okay;
> const double d; // meaningless, the 'const' is ignored.
> const structBar q; // okay
>
> 'const' means you cannot change the stuff the reference is referencing or
> the members of the struct, *but* for reference types you can change the
> reference value.
>
> s[0] = 'a'; // fails
> s = "new data"; //ok
> s.length = 2; // ok
>
> c = 'a'; // ok
>
> f.bar = 'a'; // fails
> f = new classFoo(); // okay
>
> *b = 1.0; // fails
> b = &someDouble; // ok
>
> d = 1.0; // okay
>
> q.foo = 'a'; // fails
Correct.
> 'invariant' means you cannot change the stuff the reference is referencing
> or the members of the struct, *and* for reference types you cannot change
> the reference value.
No. Invariant means that the data referenced indirectly is never
modifiable by any part of the program.
What you called 'invariant' above is 'final const'.
[snip]
> However, if this is the interpretation of 'invariant', how does one ever
> get to set the 'invariant' thing's value?
>
> invariant byte[] vCodes;
> . . .
> vCodes = LoadCodesFromFile(); // fails, no???
Right now you can only initialize invariant with literals. This aspect
of the language is still under development. (Things like the result of
some_string.dup also come to mind.)
> void func( string s )
> {
>
> string t;
> char[] u;
> u = s;
> u[0] = 'a'; // fails.
> u = s[1..4];
> u[0] = 'a'; // fails
> u = s.dup;
> u[0] = 'a' // ok
>
> t = s; // fails???
>
> }
You can't make the assignment u = s.
>> 3. The ~= operator works (somewhat surprisingly).
> void func( string s )
> {
> string t;
> char[] u;
>
> u ~= s; // ok
> s ~= 'a'; // fails ???
>
> t ~= s; // fails???
> }
s ~= a; works and is equivalent to s = s ~ a, i.e. "rebind s to the
concatenation of s and a". It's an operation that does not mutate s's
contents.
>> 4. It's very, very rare that you want to modify some random character in
>> a string, and when you do, use a char[] and then copy it back into a
>> string, or rebuild the string from slices!
>
> It is not so rare in the type of applications that I do.
You use char[] for that, and when you are done modifying, you can put
things in a string.
> Are you saying that I can do this...?
>
> string func( string s )
> {
> char[] u;
> u = s.dup;
> u[somerandomspot] = 'a';
> return u;
> }
This is sound, but tricky to typecheck. I'll have to get back to you on
that one.
> or this ... ?
>
> void func( string ref s )
> {
> char[] u;
> u = s.dup;
> u[somerandomspot] = 'a';
> s = u;
> }
Same as above.
> or this ... ?
>
> string func( string ref s )
> {
> char[] u;
> string t;
> u = s.dup;
> u[somerandomspot] = 'a';
> t = u;
> }
These last three examples work because u is temporary and not aliased
with anything. If it were, the code would be unsound. Such cases are
tricky to typecheck in the general case, but we'll look into a solution
that allows such expressive idioms without also taking risks.
> What I don't get here is the phrase "copy it back into a string". This
> sounds ambiguous to me. It could mean, "construct a new string containing
> the updated data", or "replace the original string reference with a
> reference to the updated data". But I was starting to think that
> 'invariant' meant that you couldn't change the reference value at all, so I
> don't see how one could change an 'invariant' parameter or construct an
> 'invariant' local /variable/.
Indeed, 'invariant' meant that the referenced data is invariant. The
actual variable can be rebound to any other invariant data. It's like
watching TV: you can always change your choice of watching, but you
can't modify the actual contents of programs - unless you take special
measures :o).
Andrei
More information about the Digitalmars-d
mailing list