www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Should .idup simply do nothing for arrays that are already immutable?

reply dsimcha <dsimcha yahoo.com> writes:
import std.stdio;

void main() {
    immutable foo = "FOO";
    immutable bar = foo.idup;
    writeln(foo.ptr, '\t', bar.ptr);
}

Output:
42C090  97AE40

Should we define .idup on an already-immutable array to simply do nothing?  It
seems that there is never any good reason to copy an immutable array, and it
would avoid the need to either needlessly copy an array or explicitly check
for immutability in metaprogramming situations.
Jan 08 2010
next sibling parent reply BCS <none anon.com> writes:
Hello dsimcha,

 import std.stdio;
 
 void main() {
 immutable foo = "FOO";
 immutable bar = foo.idup;
 writeln(foo.ptr, '\t', bar.ptr);
 }
 Output:
 42C090  97AE40
 Should we define .idup on an already-immutable array to simply do
 nothing?  It seems that there is never any good reason to copy an
 immutable array, and it would avoid the need to either needlessly copy
 an array or explicitly check for immutability in metaprogramming
 situations.
 

I can think of one case where I would want to force the copy: In template code where I've got a mutable or immutable object/array and I want to make a modified immutable version of it. - idup it - modify it via casting away the immutability - never change it again To do this totally correctly would requiter 2 copies, (original to mutable to immutable). The other option would be to make a mutable copy and then cast it into an immutable object.
Jan 08 2010
parent dsimcha <dsimcha yahoo.com> writes:
== Quote from BCS (none anon.com)'s article
 Hello dsimcha,
 import std.stdio;

 void main() {
 immutable foo = "FOO";
 immutable bar = foo.idup;
 writeln(foo.ptr, '\t', bar.ptr);
 }
 Output:
 42C090  97AE40
 Should we define .idup on an already-immutable array to simply do
 nothing?  It seems that there is never any good reason to copy an
 immutable array, and it would avoid the need to either needlessly copy
 an array or explicitly check for immutability in metaprogramming
 situations.

code where I've got a mutable or immutable object/array and I want to make a modified immutable version of it. - idup it - modify it via casting away the immutability - never change it again To do this totally correctly would requiter 2 copies, (original to mutable to immutable). The other option would be to make a mutable copy and then cast it into an immutable object.

I think the latter is the better way to do this. Modifying data for which immutability has been cast away is technically undefined behavior, meaning that the compiler could, if it wanted to, optimize your code in such a way (via constant folding, caching, etc.) that your modifications to the immutable data are never seen by some parts of the code. Casting mutable data to immutable is well-defined as long as you don't leave any mutable references to it.
Jan 08 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 08 Jan 2010 16:07:16 -0500, dsimcha <dsimcha yahoo.com> wrote:

 import std.stdio;

 void main() {
     immutable foo = "FOO";
     immutable bar = foo.idup;
     writeln(foo.ptr, '\t', bar.ptr);
 }

 Output:
 42C090  97AE40

 Should we define .idup on an already-immutable array to simply do  
 nothing?  It
 seems that there is never any good reason to copy an immutable array,  
 and it
 would avoid the need to either needlessly copy an array or explicitly  
 check
 for immutability in metaprogramming situations.

In fact, I think the whole dup notion needs to be revisited. idup and dup currently suffer from a very unsafe bug -- they implicitly cast the result, even if the array contents are references (http://d.puremagic.com/issues/show_bug.cgi?id=3550). Also, currently there is only one function for duping and it doesn't know whether the result is going to be immutable or mutable. My opinion is that it's better at this point in time to get rid of idup and make dup always copy its contents, and always return the same type it's called with. If you want to transform to immutable or away from immutable, it's on you to do the cast afterwards. That's the only possible safe solution ATM. idup can be an array function which does the right thing or refuses to compile (see the bug). You'd probably want cdup and mdup also. If, in the future, we are able to get a unique qualifier, then changing dup to returning unique will naturally work the way it should. As it is now, it is a hack and should be fixed. -Steve
Jan 08 2010
prev sibling next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Fri, 08 Jan 2010 22:28:32 +0100, BCS <none anon.com> wrote:

 Hello dsimcha,

 import std.stdio;
  void main() {
 immutable foo = "FOO";
 immutable bar = foo.idup;
 writeln(foo.ptr, '\t', bar.ptr);
 }
 Output:
 42C090  97AE40
 Should we define .idup on an already-immutable array to simply do
 nothing?  It seems that there is never any good reason to copy an
 immutable array, and it would avoid the need to either needlessly copy
 an array or explicitly check for immutability in metaprogramming
 situations.

I can think of one case where I would want to force the copy: In template code where I've got a mutable or immutable object/array and I want to make a modified immutable version of it. - idup it - modify it via casting away the immutability - never change it again

Don't do this. It's undefined, it's ugly, and it's wrong, and the language definitely should in no way aid such behavior.
 To do this totally correctly would requiter 2 copies, (original to  
 mutable to immutable). The other option would be to make a mutable copy  
 and then cast it into an immutable object.

The last option is the correct one, IMO. Casting a unique object to immutable is well-defined and good. -- Simen
Jan 08 2010
next sibling parent BCS <none anon.com> writes:
Hello Simen,

 On Fri, 08 Jan 2010 22:28:32 +0100, BCS <none anon.com> wrote:
 
 Hello dsimcha,
 
 import std.stdio;
 void main() {
 immutable foo = "FOO";
 immutable bar = foo.idup;
 writeln(foo.ptr, '\t', bar.ptr);
 }
 Output:
 42C090  97AE40
 Should we define .idup on an already-immutable array to simply do
 nothing?  It seems that there is never any good reason to copy an
 immutable array, and it would avoid the need to either needlessly
 copy
 an array or explicitly check for immutability in metaprogramming
 situations.

template code where I've got a mutable or immutable object/array and I want to make a modified immutable version of it. - idup it - modify it via casting away the immutability - never change it again

language definitely should in no way aid such behavior.

I didn't say I thought it was a /good/ idea. :)
Jan 09 2010
prev sibling parent BCS <none anon.com> writes:
Hello Simen,

 On Fri, 08 Jan 2010 22:28:32 +0100, BCS <none anon.com> wrote:
 
 Hello dsimcha,
 
 import std.stdio;
 void main() {
 immutable foo = "FOO";
 immutable bar = foo.idup;
 writeln(foo.ptr, '\t', bar.ptr);
 }
 Output:
 42C090  97AE40
 Should we define .idup on an already-immutable array to simply do
 nothing?  It seems that there is never any good reason to copy an
 immutable array, and it would avoid the need to either needlessly
 copy
 an array or explicitly check for immutability in metaprogramming
 situations.

template code where I've got a mutable or immutable object/array and I want to make a modified immutable version of it. - idup it - modify it via casting away the immutability - never change it again

language definitely should in no way aid such behavior.

I didn't say I thought it was a /good/ idea. :)
Jan 09 2010
prev sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2010-01-08 16:07:16 -0500, dsimcha <dsimcha yahoo.com> said:

 Should we define .idup on an already-immutable array to simply do nothing?  It
 seems that there is never any good reason to copy an immutable array, and it
 would avoid the need to either needlessly copy an array or explicitly check
 for immutability in metaprogramming situations.

I think it should indeed return the same immutable array. One goal of immutable is to avoid having to make unnecessary copies. If you call idup it means you want an immutable version of the array, so it shouldn't matter if it's a copy or if it's the same, as long as it's immutable (as in guarantied to never change) and it contains the right data. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 09 2010