string vs. const(char)[] on the function signature

Steven Schveighoffer schveiguy at yahoo.com
Thu Sep 13 07:34:50 PDT 2012


I know this is really old, but just catching up on old posts.

On Fri, 13 Jul 2012 13:19:34 -0400, Ali Çehreli <acehreli at yahoo.com> wrote:

> tl;dr - Please see the conclusion section below.

[snip]

> CONCLUSION:
>
> * For parameters of reference types that are not modified in the  
> function, const is a better choice than immutable because const can take  
> both mutable and immutable.
>
> (I still include this among the guidelines under the "How to use"  
> section here:
>
>    http://ddili.org/ders/d.en/const_and_immutable.html
> )
>
> * The choice above complicates matters when the parameter needs to be  
> forwarded to a function that takes as immutable, because 'const' erases  
> the mutability information of the actual variable.
>
> * The solution is to make the function a template so that the actual  
> type is retained. This solution prevents unnecessary copies when the  
> actual variable is already immutable.

IMO, a function that does not utilize the benefits of immutable should  
actually be re-labeled const or inout.

For example (please, don't suggest I use some tricks to make this a one  
liner, it's an example):

int foo(immutable(int)[] arr)
{
    int x = 0;
    foreach(m ; arr)
       x += m;
    return x;
}

Clearly, this does not need to be immutable.  Making it immutable does not  
help or change anything.

However, we have this special case of char[] arrays, because the most  
common type used is 'string', which is immutable.

But using string has benefits -- you can simply store the string somewhere  
without worrying it gets changed or erased.

However, the library (phobos) should not force you into immutable ever.   
Yes, strings are immutable, and we can have some benefits for that, but  
phobos shouldn't make it difficult to avoid immutable, it should not have  
an opinion there.

Almost all phobos functions that accept 'strings' should take  
const(char)[] or inout(char)[], not string.

Now, we cannot control what we don't write, so it's quite easy to see that  
someone might label something as string when it should have been  
inout(char)[], and you simply have to deal with it.  I think the correct  
solution is to define both an inout/const version, which uses .idup, and  
an immutable version which uses does not.  There is no reason to have a  
mutable version.

It would be nice to be able to make a recommended pattern that allows you  
to avoid code duplication.  Something like this:

template constOrImmutable(T)
{
    static if(is(T == immutable))
       alias T constOrImmutable;
    else
       alias const(T) constOrImmutable;
}
void foo(T)(constOrImmutable!(T)[] arg)
{
     bar(to!(immutable(T)[])(arg)); // should idup if T is not immutable
}

Of course, this still results in two identical instantiations for mutable  
and const, even though the resulting code is the same.  Hopefully the  
compiler optimizes this out.

-Steve


More information about the Digitalmars-d-learn mailing list