Implicit conversion of unique objects to mutable and immutable

Jonathan M Davis jmdavisProg at gmx.com
Tue Jun 21 16:02:43 PDT 2011


On 2011-06-21 15:25, Ali Çehreli wrote:
> (Note: I have a feeling that this must be related to the old 'unique'
> discussions, which I had somehow managed to stay out of. If so, I
> apologize for repeating an old story.)
> 
> It is most useful for a function to return the most mutable type unless
> there is good reason not to. Do you agree?

No. In a lot of cases, what you generally want is immutable, not mutable. In 
particular, if you're talking about strings, we favor string, wstring, and 
dstring over char[], wchar[], or dchar[] unless you actually need to alter the 
string. The default is to use immutable. You save memory, it works well with 
threading, and it increases the opportunites for optimization. There's 
generally little benefit to having strings be mutable (which is why string is 
an alias to immutable(char)[], not char[]). char[], wchar, and dchar[] are 
there if you need them (and obviously sometimes you do), but in general, 
immutable is preferred, because it's generally more efficient.

Now, outside of strings, it varies a lot more as to whether immutable, const 
or mutable is preferred, since there are plenty of other types which get 
mutated all of the time. But there are still huge advantages to const and 
immutable in the general case, so there are plenty of situations where 
defaulting to the least mutable type possible is the best solution. It does 
vary depending on the situation, however.

> foo() makes a fresh result and
> returns it:
> 
> char[] foo()
> {
> char[] result;
> return result;
> }
> 
> The caller can get the result as a char[] and modify it:
> 
> char[] result = foo();
> result[0] = 'A'; // assume a valid element
> 
> But what if the caller wants to treat the returned value as immutable:
> 
> string result = foo();
> 
> That's currently a compilation error: "Error: cannot implicitly convert
> expression (foo()) of type char[] to string"
> 
> When it makes sense, we have std.exception.assumeUnique() for the caller
> to use:
> 
> import std.exception;
> 
> // ...
> 
> char[] result = foo();
> string immutable_result = assumeUnique(result);
> 
> But that's the wrong thing to do, as foo() may be changed in the future
> to return a non-unique result. I think the language should have the
> 'unique' qualifier so that foo() could use it on the return type:
> 
> unique char[] foo()
> {
> // ...
> }
> 
> and the unique objects could be converted to immutable or mutable
> implicitly:
> 
> string immutable_result = foo(); // fine
> char[] mutable_result = foo(); // fine too
> 
> Is this whole thing the same as that old 'unique' discussion? :)

It relates - particularly if foo is strongly pure, because then it's 
guaranteed that the result of foo is either unique or it's immutable and 
therefore it doesn't matter.

> But anyway... How do you solve the problem of deciding the return type of
> such functions?

Generally, you pick. Normally, we favor string over char[]. Immutability is 
generally favored over mutability when it comes to strings. The major elements 
which affect what a string function returns though are the function's 
arguments and what the function actually does. If the function is going to 
allocate a string, then it's generally going to return immutable. But if it's 
going to return a slice, then its return type is going to depend on what you 
passed in (in which case, the function is templated or it just uses const).

Of course, you can always templatize the function and have it default to 
whatever string type you want to be the default, and then pass the type that 
you want if you want a different one.

string s = foo!string();
char[] t = foo!(char[])();

But I don't think that that's particularly normal thing to do. Phobos 
generally either just uses string, or the type of string that it returns 
depends on its arguments (generally because it's going to return a slice 
rather than a new string).

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list