Tricky semantics of ranges & potentially numerous Phobos bugs

Jonathan M Davis jmdavisProg at gmx.com
Tue Oct 16 12:21:18 PDT 2012


On Tuesday, October 16, 2012 19:51:09 Tommi wrote:
> On Tuesday, 16 October 2012 at 17:19:26 UTC, Jonathan M Davis
> 
> wrote:
> > 1. There is no generic way to deep copy stuff.

There is no standard function for copying anything. dup and idup are array-
specific. It's a commonly used function name for a clone function on objects, 
but that's just a convention and not even necessarily a consistently used one. 
Some types are value types and so simply making a copy of them does a deep 
copy, whereas others are reference types and making a copy only does a shallow 
copy (hence why save was created for ranges). There's no way to look at a type 
and know how to correctly copy it. The best that could be done would be to 
standardize on dup, in which case it would be defined it for all built-in stuff 
via UFCS, and any user-defined stuff that wanted to be generically copied would 
define it. But we haven't done anything like that.

But really, not even that would be enough, because dup doesn't do a deep copy 
on arrays. It does something in between a shallow copy and a deep copy. It 
copies the array itself rather than the pointer, meaning that you get a 
totally separate array, but it doesn't do a deep copy of the elements, so if 
you had an array of reference types, anything done to the duped array's 
elements (other than assigning them new references) will affect the originals.

> How about a deep-assign operator? The compiler could implicitly
> define it at least for arrays and for structs that don't have
> mutable indirection:
> 
> struct MyStruct
> {
> int _value;
> 
> // implicit:
> ref MyStruct opDeepAssign(ref const MyStruct ms)
> {
> this = ms;
> return this;
> }
> }
> 
> int[] array1 = [1, 2, 3];
> int[] array2;
> array2.opDeepAssign(array1); // array2 = array1.dup;
> 
> And there would be hasDeepAssign!T traits and whatnot.

Something like that could probably be done, but that's not really all that 
different from just defining dup for stuff and having a hasDup trait, which can 
be done without any changes to the language like opDeepAssign would require. 
And again, it doesn't quite do the job due to how dup on arrays work. We'd 
probably need to add a function to the standard library (e.g. deepCopy) which 
would be defined for all built-in types and which user-defined types could define 
(with something hasDeepCopy being there to check for it), and then code could 
use that for doing deep copies. So again, it's possible, but it doesn't 
currently exist.

- Jonathan M Davis


More information about the Digitalmars-d mailing list