Inability to dup/~ for const arrays of class objects

Ali Çehreli acehreli at yahoo.com
Thu May 30 08:50:37 PDT 2013


On 05/30/2013 01:58 AM, Maxim Fomin wrote:

 > On Thursday, 30 May 2013 at 07:57:41 UTC, Ali Çehreli wrote:
 >> On 05/30/2013 12:11 AM, Maxim Fomin wrote:
 >> > As a general programming notion - yes, in D (array spec page):
 >> > "Dynamic arrays consist of a length and a pointer to the
 >> array data."
 >>
 >> Then the spec is wrong because that is the definition of a slice. The
 >> reason is, there is no dynamic array is sight below but a static array
 >> and a slice:
 >>
 >>     int[10] arr;
 >>     int[] slice = arr;
 >>     assert(slice.ptr == &arr[0]);  // (yes, same as arr.ptr)
 >
 > No, spec is right and article is wrong. It uses incorrect definition and
 > calls correct definitions as incorrect.

Your definition of "correct" depends stems from the fact that it is what 
the spec says. If we take the spec as the final word, you are right. 
However, there are historical reasons why terminology sometimes lag 
behind reality and sometimes never change.

Steven's article is trying to correct or avoid misunderstandings of 
novices and experts alike. I have been confused a lot about D's array 
and slice semantics. Only after seeing dynamic arrays separate from 
slices it finally made (more) sense to me.

The code above is a good example of the confusion. If we tell a novice 
that there are two entities in that code, the novice gets confused. The 
reason is, when it comes to actual elements, there is a singe array. 
Calling a single array two is a confusion.

Another example:

void foo(int[] a, int[] b, int[] c)
{
     // ...
}

If we call a novice that the function takes three dynamic arrays, then 
the novice gets confused. (Even the experts get confused because the bug 
that you mention later below about variadic arguments is because the 
spec calls it dynamic array.)

The reality of the code above is that there may be a single array 
depending how the function is called.

The solution for the confusion is to call the entity a "slice" for both 
code fragments above.

 > static assert(typeof(slice) == typeof(int[])); // int[] type is dynamic
 > array

You call it a "dynamic array" because the spec does so. Staying with 
that definition, you are absolutely correct. As Steven said, we can't 
argue further.

However, 'slice' up there is not an array itself; it is just a view of 
existing elements, wherever they are.

 > this checks that object 'slice' is of type dynamic array. Note, that
 > notion of slice is not embebed into compiler at all (you cannot test
 > whether some object is of type 'slice' or not).

I am happy with the definition that a slice is a length and a pointer to 
the first element that it provides access to. This definition exists in 
the compiler.

 >> (I know I am repeating the article at this point but it happens to be
 >> the fact.) If there is no dynamic array to speak of above, what is a
 >> dynamic array then? The answer is, dynamic array is an entity that is
 >> owned and managed by the D runtime.
 >
 > This is recalling incorrect definitions from article. You are simply
 > assuming that dynamic array is runtime memory and everything which does
 > not refer to runtime memory is not a dynamic array. This is wrong
 > because dynamic array is not defined to be runtime memory and not
 > promised to be in 100% cases.

I agree with your quote from another post in the same thread:

 > Confusion comes from calling a dynamic array as a slice

Absolutely! :)

 > and runtime memory
 > as a dynamic array.

(I assume you mean "run-time" there, as in "something happens during the 
execution of the program." Otherwise, "runtime" may also refer to "the D 
runtime", the layer that makes use of the GC to do its magic.)

With that assumption, I never called run-time memory a dynamic array. I 
meant that dynamic arrays are owned and managed by "the D runtime".

 > Memory kind allocation and dynamic/static kind of array
 > are quite ortogonal issues with high correlation between dynamic 
array and
 > heap memory which is not 1.

I agree completely.

 > Consider example with typesafe variardic
 > functions when dynamic array is constructed on caller side from stack
 > memory. It is of type dynamic array yet it is not from runtime memory.

We are using different meanings of "dynamic". Both "static" and 
"dynamic" mean many different things:

dynamic may mean:

* happens at run-time

* sits on the heap

* resizable

* does not have automatic duration

* more?

static may mean:

* initialized at compile time

* sits on the stack

* sits on the code segment

* has automatic duration

* gets destroyed after main exits

* not resizable

* more?

See, that is yet another problem with spec language. The spec must pick 
a word to describe something, which doesn't work in every situation.

That is why I prefer "fixed-length array" over "static array". "static" 
and "dynamic" carry too many meanings.

Getting back to your comment:

 > It is of type dynamic array yet it is not from runtime memory.

Agreed that the variadic argument is created at runtime and that it is 
not from "dynamic memory".

 > By the way, this is good example of how incorrect definition confuses
 > people and make them to write buggy code. I remember at least two bugs
 > in bugzilla when people were complaining that 'dynamic array from
 > typesafe variardic function seems not to refer to runtime memory'.

Isn't that a good example of my point? Just because the spec calls it a 
"dynamic array" that the programmers make an assumption. If it were 
called a "slice" then it would emphasize the fact that it could be 
referring to elements anywhere.

 >> For the above code to finally involve a dynamic array, we can add an
 >> element to 'slice':
 >>
 >>     slice ~= 7;
 >>     assert(slice.ptr != &arr[0]);
 >>
 >> Now there is a dynamic array but it is not our 'slice' that is the
 >> dynamic array. Here is the proof:
 >>
 >>     slice = arr[5 .. $];
 >>     assert(slice.ptr == &arr[5]);
 >>
 >> Has 'slice' been a dynamic array until that last assignment and
 >> suddenly become a slice again? No, D does not involve type changes
 >> like that. It has always been a slice, which is not the same thing as
 >> a dynamic array.
 >
 > One of the funny consequences of using incorrect definition is that is
 > forces to call an entity as not a dynamic array and after some
 > manipulations the same entity to call a dynamic array. This is obviously
 > wrong because it is the same object.

And that same object is just a view of elements that are not owned by 
themselves. The code above makes sense only by this understanding. For 
only by this definition 'slice' above does *not* change definition. It 
is always a slice and a slice is just a view into some elements.

Ali



More information about the Digitalmars-d mailing list