On Tue, 21 Jun 2011 20:31:19 -0400, Jonathan M Davis <[email protected]>
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