Thread overview
What is the best declaration type for a string like parameter?
Jan 28, 2016
Puming
Jan 28, 2016
sigod
Jan 29, 2016
Puming
Jan 28, 2016
Adam D. Ruppe
Jan 28, 2016
Gary Willoughby
Jan 28, 2016
tsbockman
Jan 29, 2016
Puming
January 28, 2016
I have a function that reads a line of string and do some computation.

I searched the forum and found that people use `const(char)[]` or `in char[]` to accept both string and char[] arguments.


What's the difference between `const(char)[]` and `in char[]`?

If they are not the same, then which is better? If they are, then why both forms exists?

I found it a bit confusing and not quite readable, so I made an alias:

alias str = const(char)[]

and so far it works. But if `in char[]` is better, then I cannot alias it:

alias str = in char[]

this does not compile.
January 28, 2016
On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
> I have a function that reads a line of string and do some computation.
>
> I searched the forum and found that people use `const(char)[]` or `in char[]` to accept both string and char[] arguments.
>
>
> What's the difference between `const(char)[]` and `in char[]`?
>
> If they are not the same, then which is better? If they are, then why both forms exists?

`in char[]` is short for `scope const char[]` or `scope const(char[])`.

See http://dlang.org/spec/function.html#parameters

It depends on the situation. If possible I would use `in` modifier. If not then just `const`.

> I found it a bit confusing and not quite readable, so I made an alias:
>
> alias str = const(char)[]
>
> and so far it works. But if `in char[]` is better, then I cannot alias it:
>
> alias str = in char[]
>
> this does not compile.

Please, don't define such aliases. I'm sure a lot of developers will find it confusing. As I do.

`const(char)[]` or `in char[]` is perfectly understandable as soon as you know what it means.

Also, read this: http://dlang.org/spec/const3.html
January 28, 2016
On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
> I searched the forum and found that people use `const(char)[]` or `in char[]` to accept both string and char[] arguments.

There's also the hyper-generic signatures Phobos uses like

void foo(S)(S s) if(isSomeString!S)

and the input range types and the isConvertibleToString, etc., if you want to take different encodings, or string-like objects, or string wrappers/generators, etc.

But for just both string and char[], yeah, const is the way to do it.

> What's the difference between `const(char)[]` and `in char[]`?

`in char[]` means the whole parameter is const and you are not supposed to escape it. It expands to `const scope char[]`, with the const on the outermost level and `scope` too which means a reference to it should never escape this scope.

const(char)[] global;

void foo(const(char)[] arg) {
   arg[0] = 'a'; // illegal, the contents are const
   arg = "whole new thing"; // legal, you are allowed to rebind
   global = arg; // legal, you can escape it too
}



contrast with:


const(char)[] global;

void foo(in char[] arg) {
   arg[0] = 'a'; // illegal, the contents are const
   arg = "whole new thing"; // illegal, arg is const too
   global = arg; // illegal, you can't escape the reference either
}



Note that the `global = arg` will still compile - the compiler doesn't properly check this right now - but the spec says it is illegal and may be optimized or statically checked differently at any time, so if you do it you are in undefined behavior territory. Don't do it!


> If they are not the same, then which is better? If they are, then why both forms exists?

I like `in char[]` if you intend to follow all the rules. Otherwise, use the const version, which cannot be aliased because it isn't a type , it is a parameter storage class and only valid in that context.
January 28, 2016
On Thursday, 28 January 2016 at 15:10:38 UTC, Adam D. Ruppe wrote:
> On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
>> I searched the forum and found that people use `const(char)[]` or `in char[]` to accept both string and char[] arguments.
>
> There's also the hyper-generic signatures Phobos uses like
>
> void foo(S)(S s) if(isSomeString!S)

Yep, this is your answer.

void foo(S)(S s) if(isSomeString!S)
{
    //use s
}

Call normally as it can implicitly determine the type of S:

foo("bar");
January 28, 2016
On Thursday, 28 January 2016 at 17:32:31 UTC, Gary Willoughby wrote:
> On Thursday, 28 January 2016 at 15:10:38 UTC, Adam D. Ruppe wrote:
>> On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
>>> I searched the forum and found that people use `const(char)[]` or `in char[]` to accept both string and char[] arguments.
>>
>> There's also the hyper-generic signatures Phobos uses like
>>
>> void foo(S)(S s) if(isSomeString!S)
>
> Yep, this is your answer.
>
> void foo(S)(S s) if(isSomeString!S)
> {
>     //use s
> }
>
> Call normally as it can implicitly determine the type of S:
>
> foo("bar");

Template bloat awaits those who take this approach to every problem. In practice, `in char[]` is probably better for most code.
January 29, 2016
On Thursday, 28 January 2016 at 15:03:38 UTC, sigod wrote:
> On Thursday, 28 January 2016 at 13:36:46 UTC, Puming wrote:
>> [...]
>
> `in char[]` is short for `scope const char[]` or `scope const(char[])`.
>
> See http://dlang.org/spec/function.html#parameters
>
> It depends on the situation. If possible I would use `in` modifier. If not then just `const`.
>
>> [...]
>
> Please, don't define such aliases. I'm sure a lot of developers will find it confusing. As I do.
>
> `const(char)[]` or `in char[]` is perfectly understandable as soon as you know what it means.
>
> Also, read this: http://dlang.org/spec/const3.html

Thanks. Now I get it.

Yes it is understandable now, but as a newbie the question "Why my function that accepts a string does not work with lines in file?" will pop.
January 29, 2016
On Thursday, 28 January 2016 at 15:10:38 UTC, Adam D. Ruppe wrote:
>
> But for just both string and char[], yeah, const is the way to do it.
>
> [...]

Thanks for the clear explaination. So `in char[]` is stricter (and safer) than `const(char)[]`. I will stick to that.