Implicit conversion of unique objects to mutable and immutable

Steven Schveighoffer schveiguy at yahoo.com
Wed Jun 22 05:09:40 PDT 2011


On Tue, 21 Jun 2011 20:31:19 -0400, Jonathan M Davis <jmdavisProg at gmx.com>  
wrote:

> On 2011-06-21 16:50, Ali Çehreli wrote:
>> On Tue, 21 Jun 2011 23:02:43 +0000, Jonathan M Davis wrote:
>> > 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.
>>
>> I agree with all of that, but it should not be the function that
>> restricts the caller. The function should return immutable only when the
>> result is really immutable.
>>
>> If the returned object is mutable and unique, it is pretentious of the
>> function to evangelically return immutable. :) Besides, the caller can't
>> know whether it was actually mutable but was returned as immutable
>> because it was the right thing to do. Otherwise the caller could cast to
>> mutable to save a copy.
>>
>> > immutable is preferred, because it's generally more efficient.
>>
>> Not in this case because the caller must make a copy to mutate further.
>> If the function could return 'unique mutable' and if that could be  
>> casted
>> to immutable implicitly, then all would be fine.
>
> As I said, in Phobos, when a new string must be allocated, the type  
> returned
> is generally string (so it's immutable), whereas if the result of the  
> function
> is likely to be slice of the string passed in, then the function is  
> templated
> to return the same type of string as was passed to it. There's no  
> extraneous
> copying going on in order to return string. The _only_ case where it's
> arguably forced on the caller is in the case where a copy _must_ be  
> made, in
> which case the function returns string rather than char[].

The issue is that newly-allocated data can be considered unique.  It would  
be advantageous for this to implicitly cast to mutable *or* immutable.  In  
other words, imposing the immutable limitation is artificial, and in some  
cases makes things less usable.

Think about dup and idup.  Wouldn't it be more straightforward if you just  
did dup and assigned it to whatever type you wanted?  Wouldn't it be more  
universal if all functions that create new data didn't have to have a  
mutable and immutable version?

If it's a slice of the input, it should be using inout, but inout is  
broken.

I think the clear path here is to use strong-pure functions to implicitly  
cast to immutable.  Such functions would have to return char[] because if  
it returns const(char)[] or immutable(char)[], it's possible the result is  
a slice of the input.

For example, the following function can only return a newly-allocated  
char[] (without using casts):

pure char[] foo(immutable(char)[] arg1, const(char)[] arg2)) {...}

So it is safe to assume the return is unique.

To answer Ali, we can add unique to the language, but this adds yet  
another type of const (unique has to do with const).  This might not go  
over well in a language with already 4 types of const (const, mutable,  
immutable, inout).  Where it does help quite a bit is for sharing mutable  
data, but of course, we can start building library constructs that allow  
that.

-Steve


More information about the Digitalmars-d-learn mailing list