www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - auto + Top-level Const/Immutable

reply dsimcha <dsimcha yahoo.com> writes:
The changes made to IFTI in DMD 2.057 are great, but they reveal another 
hassle with getting generic code to play nice with const.

import std.range, std.array;

ElementType!R sum(R)(R range) {
     if(range.empty) return 0;
     auto ans = range.front;
     range.popFront();

     foreach(elem; range) ans += elem;
     return ans;
}

void main() {
     const double[] nums = [1, 2, 3];
     sum(nums);
}

test.d(8): Error: variable test9.sum!(const(double)[]).sum.ans cannot 
modify const
test.d(14): Error: template instance test9.sum!(const(double)[]) error 
instantiating

Of course this is fixable with an Unqual, but it requires the programmer 
to remember this every time and breaks for structs with indirection. 
Should we make `auto` also strip top-level const from primitives and 
arrays and, if const(Object)ref gets in, from objects?
Dec 20 2011
next sibling parent "Martin Nowak" <dawg dawgfoto.de> writes:
On Tue, 20 Dec 2011 15:23:31 +0100, dsimcha <dsimcha yahoo.com> wrote:

 The changes made to IFTI in DMD 2.057 are great, but they reveal another  
 hassle with getting generic code to play nice with const.

 import std.range, std.array;

 ElementType!R sum(R)(R range) {
      if(range.empty) return 0;
      auto ans = range.front;
      range.popFront();

      foreach(elem; range) ans += elem;
      return ans;
 }

 void main() {
      const double[] nums = [1, 2, 3];
      sum(nums);
 }

 test.d(8): Error: variable test9.sum!(const(double)[]).sum.ans cannot  
 modify const
 test.d(14): Error: template instance test9.sum!(const(double)[]) error  
 instantiating

 Of course this is fixable with an Unqual, but it requires the programmer  
 to remember this every time and breaks for structs with indirection.  
 Should we make `auto` also strip top-level const from primitives and  
 arrays and, if const(Object)ref gets in, from objects?
At a first thought yes. I always end up using 'const/immutable var = exp' if I want the other one and 'auto var = exp' with const pretty often causes troubles.
Dec 20 2011
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, December 20, 2011 09:23:31 dsimcha wrote:
 The changes made to IFTI in DMD 2.057 are great, but they reveal another
 hassle with getting generic code to play nice with const.
 
 import std.range, std.array;
 
 ElementType!R sum(R)(R range) {
 if(range.empty) return 0;
 auto ans = range.front;
 range.popFront();
 
 foreach(elem; range) ans += elem;
 return ans;
 }
 
 void main() {
 const double[] nums = [1, 2, 3];
 sum(nums);
 }
 
 test.d(8): Error: variable test9.sum!(const(double)[]).sum.ans cannot
 modify const
 test.d(14): Error: template instance test9.sum!(const(double)[]) error
 instantiating
 
 Of course this is fixable with an Unqual, but it requires the programmer
 to remember this every time and breaks for structs with indirection.
 Should we make `auto` also strip top-level const from primitives and
 arrays and, if const(Object)ref gets in, from objects?
Assuming that the assignment can still take place, then making auto infer non- const and non-immutable would be an improvement IMHO. However, there _are_ cases where you'd have to retain const - a prime example being classes. But value types could have const/immutable stripped from them, as could arrays using their tail-constness. - Jonathan M Davis
Dec 20 2011
parent reply "dsimcha" <dsimcha yahoo.com> writes:
On Tuesday, 20 December 2011 at 17:46:40 UTC, Jonathan M Davis 
wrote:
 Assuming that the assignment can still take place, then making 
 auto infer non-
 const and non-immutable would be an improvement IMHO. However, 
 there _are_ cases where you'd have to retain const - a prime 
 example being classes. But value types could have 
 const/immutable stripped from them, as could arrays using their 
 tail-constness.

 - Jonathan M Davis
Right. The objects would only be head de-constified if Michael Fortin's patch to allow such things got in. A simple way of explaining this would be "auto removes top level const from the type T if T implicitly converts to the type that would result".
Dec 20 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/20/2011 07:16 PM, dsimcha wrote:
 On Tuesday, 20 December 2011 at 17:46:40 UTC, Jonathan M Davis wrote:
 Assuming that the assignment can still take place, then making auto
 infer non-
 const and non-immutable would be an improvement IMHO. However, there
 _are_ cases where you'd have to retain const - a prime example being
 classes. But value types could have const/immutable stripped from
 them, as could arrays using their tail-constness.

 - Jonathan M Davis
Right. The objects would only be head de-constified if Michael Fortin's patch to allow such things got in. A simple way of explaining this would be "auto removes top level const from the type T if T implicitly converts to the type that would result".
Yes, having to use auto x = cast()y; is quite annoying, I'd like this change to happen. BTW: What will happen with cast()classRef once we have head-mutable class references?
Dec 20 2011
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2011-12-20 18:39:02 +0000, Timon Gehr <timon.gehr gmx.ch> said:

 On 12/20/2011 07:16 PM, dsimcha wrote:
 On Tuesday, 20 December 2011 at 17:46:40 UTC, Jonathan M Davis wrote:
 Assuming that the assignment can still take place, then making auto
 infer non-
 const and non-immutable would be an improvement IMHO. However, there
 _are_ cases where you'd have to retain const - a prime example being
 classes. But value types could have const/immutable stripped from
 them, as could arrays using their tail-constness.
 
 - Jonathan M Davis
Right. The objects would only be head de-constified if Michael Fortin's patch to allow such things got in. A simple way of explaining this would be "auto removes top level const from the type T if T implicitly converts to the type that would result".
Yes, having to use auto x = cast()y; is quite annoying, I'd like this change to happen. BTW: What will happen with cast()classRef once we have head-mutable class references?
Same as pointers. With classRef of type "const(Object)", "cast()classRef" becomes of the head-mutable type: "const(Object)ref". -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 20 2011
prev sibling parent "Martin Nowak" <dawg dawgfoto.de> writes:
On Tue, 20 Dec 2011 19:16:26 +0100, dsimcha <dsimcha yahoo.com> wrote:

 On Tuesday, 20 December 2011 at 17:46:40 UTC, Jonathan M Davis wrote:
 Assuming that the assignment can still take place, then making auto  
 infer non-
 const and non-immutable would be an improvement IMHO. However, there  
 _are_ cases where you'd have to retain const - a prime example being  
 classes. But value types could have const/immutable stripped from them,  
 as could arrays using their tail-constness.

 - Jonathan M Davis
Right. The objects would only be head de-constified if Michael Fortin's patch to allow such things got in. A simple way of explaining this would be "auto removes top level const from the type T if T implicitly converts to the type that would result".
Auto declares a variable initialized with a copy of the rhs expression.
Dec 20 2011