Thread overview
A matter of inout
Jul 27, 2012
bearophile
Jul 27, 2012
Dmitry Olshansky
Jul 27, 2012
Artur Skawina
Jul 27, 2012
bearophile
Jul 27, 2012
bearophile
Jul 27, 2012
Ali Çehreli
Jul 27, 2012
Artur Skawina
July 27, 2012
This program used to compile in DMD 2.059:


import std.stdio;
inout(T[]) forwardDifference(T)(inout(T[]) s, in int n) pure {
    foreach (_; 0 .. n)
        s[] -= s[1 .. $];
    return s[0 .. $-n];
}
void main() {
    immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
    foreach (level; 0 .. A.length)
        writeln(forwardDifference(A.dup, level));
}


Now it gives:

test.d(5): Error: slice s[] is not mutable
test.d(12): Error: template instance test.forwardDifference!(double) error instantiating

Is it a 2.060 regression (or it's caused by a bug fix)?

Bye,
bearophile
July 27, 2012
On 27-Jul-12 19:53, bearophile wrote:
> This program used to compile in DMD 2.059:
>
>
> import std.stdio;
> inout(T[]) forwardDifference(T)(inout(T[]) s, in int n) pure {
>      foreach (_; 0 .. n)
>          s[] -= s[1 .. $];
>      return s[0 .. $-n];
> }
> void main() {
>      immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
>      foreach (level; 0 .. A.length)
>          writeln(forwardDifference(A.dup, level));
> }
>
>
> Now it gives:
>
> test.d(5): Error: slice s[] is not mutable
> test.d(12): Error: template instance test.forwardDifference!(double)
> error instantiating
>
> Is it a 2.060 regression (or it's caused by a bug fix)?
>

If it compiled before then I'd think it's a regression.



-- 
Dmitry Olshansky
July 27, 2012
On 07/27/12 17:53, bearophile wrote:
> This program used to compile in DMD 2.059:
> 
> 
> import std.stdio;
> inout(T[]) forwardDifference(T)(inout(T[]) s, in int n) pure {
>     foreach (_; 0 .. n)
>         s[] -= s[1 .. $];
>     return s[0 .. $-n];
> }
> void main() {
>     immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
>     foreach (level; 0 .. A.length)
>         writeln(forwardDifference(A.dup, level));
> }
> 
> 
> Now it gives:
> 
> test.d(5): Error: slice s[] is not mutable
> test.d(12): Error: template instance test.forwardDifference!(double) error instantiating
> 
> Is it a 2.060 regression (or it's caused by a bug fix)?

'inout' basically means 'local const' - if you'd allow inout
data to be modified then it wouldn't be possible to call the
function with a const or immutable argument - which is the
whole point of inout...
You probably want 'inout(T)[]' if you're going to alter the
array.

artur
July 27, 2012
Artur Skawina:

> 'inout' basically means 'local const' - if you'd allow inout
> data to be modified then it wouldn't be possible to call the
> function with a const or immutable argument - which is the
> whole point of inout...
> You probably want 'inout(T)[]' if you're going to alter the
> array.

Using inout(T)[] gives the same error:

import std.stdio;
inout(T)[] forwardDifference(T)(inout(T)[] s, in int n) pure {
    foreach (_; 0 .. n)
        s[] -= s[1 .. $];
    return s[0 .. $ - n];
}
void main() {
    immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
    foreach (level; 0 .. A.length)
        writeln(forwardDifference(A.dup, level));
}


Bye,
bearophile
July 27, 2012
Artur Skawina:

> 'inout' basically means 'local const' - if you'd allow inout
> data to be modified then it wouldn't be possible to call the
> function with a const or immutable argument - which is the
> whole point of inout...

dmd 2.059 was wrong then.

Bye,
bearophile
July 27, 2012
On 07/27/12 19:06, bearophile wrote:
> Artur Skawina:
> 
>> 'inout' basically means 'local const' - if you'd allow inout
>> data to be modified then it wouldn't be possible to call the
>> function with a const or immutable argument - which is the
>> whole point of inout...
>> You probably want 'inout(T)[]' if you're going to alter the
>> array.
> 
> Using inout(T)[] gives the same error:
> 
> import std.stdio;
> inout(T)[] forwardDifference(T)(inout(T)[] s, in int n) pure {
>     foreach (_; 0 .. n)
>         s[] -= s[1 .. $];
>     return s[0 .. $ - n];
> }
> void main() {
>     immutable A = [90.5, 47, 58, 29, 22, 32, 55, 5, 55, 73.5];
>     foreach (level; 0 .. A.length)
>         writeln(forwardDifference(A.dup, level));
> }

This alters not only the array, but also modifies the elements.

Using just 'T' instead of 'inout(T)' will do the right thing; why would you like to use inout in cases like this one? 'inout' allows you to not write two or more /identical/ function bodies when the code can deal with immutable/const/mutable; functions that modify the data in-place obviously can't do that.

artur
July 27, 2012
On 07/27/2012 10:13 AM, bearophile wrote:
> Artur Skawina:
>
>> 'inout' basically means 'local const' - if you'd allow inout
>> data to be modified then it wouldn't be possible to call the
>> function with a const or immutable argument - which is the
>> whole point of inout...
>
> dmd 2.059 was wrong then.

I think so.

I have understood that aspect of inout recently: since the function is not a template (bear with me please! I know it is a template here :)), there will be a single instance of it. Since that instance must work with mutable and immutable, the parameter cannot be modified inside the function.

Even if the function is never called with immutable, the compiler must compile the code as if 'inout' is spelled as 'const'.

The above makes sense for a regular function. I guess the guideline here is not to use inout on a template parameter as it doesn't make sense because T carries that information anyway.

Ali