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