www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A matter of inout

reply "bearophile" <bearophileHUGS lycos.com> writes:
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
Jul 27 2012
next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
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
Jul 27 2012
prev sibling next sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
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
Jul 27 2012
next sibling parent Artur Skawina <art.08.09 gmail.com> writes:
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
Jul 27 2012
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Jul 27 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Jul 27 2012
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
Jul 27 2012