On 11/09/2010 09:36 AM, spir wrote:
On Mon, 8 Nov 2010 17:08:32 -0800
Jonathan M Davis<jmdavisp...@gmx.com>  wrote:

As Jesse says, they _are_ passed by reference. The struct itself _is_ the
reference.

(Well, that is a sensible redefinition of "reference"; but it is simply _not_ 
what the word means in any other context.)

It is true that the inner, hidden, memory area (static array) containing the elements is 
indeed referenced, actually "pointed", from the dynamic array struct:

struct ValueArray(Element) {
     Element* elements;
     uint length;
}
(Well, actually, this may not be a struct, but it's easier to imagine it so.)

But: the dyn array itself, meaning the struct, is not referenced: "a2 = a1" 
copies it, as well as parameter passing. And the fact that the internal memory is 
referenced is an implementation detail that should *not* affect semantics. The inner 
pointer is there because we need some kind of indirection to implement variable-size 
thingies, and the means for this is pointers.
This is precisely where&  why people get bitten: implementation leaks out into 
semantics.
Actually, one could conceptually replace the (pointer,length) pair by a single 
field of type MemoryArea -- which would be a plain value. Then, there would be 
no more (visible) pointer in the dyn array, right? (Actually, it would just be 
hidden deeper inside the MemoryArea field... but that is again implementation 
detail!)

We should not mess up pointers used for implementation mechanics, like in the 
case of dyn arrays, or more generally variable size data structure, with 
pointers used as true references carrying semantics, like in the case of the 
difference between struct and class.

And precisely, replacing array struct by a class, or explicitely referencing 
the struct, would make a *reference* dyn array type. See below an example of a 
primitive sort of such an array type (you can only put new elements in it ;-), 
implemented as class.
After "a2 = a1", every change to one of the vars affects the other var; whether 
the change requires reallocation is irrelevant; this detail belongs to implementation, 
not to semantics.
Now, replace class with struct and you have a type for *value* dyn arrays. 
Which works exactly like D ones.
The assertion will fail; and output should be interesting ;-)

Hope it's clear, because I cannot do better.
I do not mean that D arrays are bad in any way. They work perfectly and are very efficient. 
Enforcing a true interface between implementation and semantics would certainly have a 
relevant cost in terms of space&  time. But please, stop stating D arrays are 
referenced if you want newcomers to have a chance&  understand the actual behaviour, to 
use them without beeing constantly bitten, and to stop&  complain.


Denis

class RefArray(Element) {
     Element* elements;
     uint length;
     private uint capacity;
     this () {
         this.elements = cast(Element*) malloc(Element.sizeof);
         this.capacity = 1;
         this.length = 0;
     }
     void reAlloc() {
         writeln("realloc");
         this.capacity *= 2;
         size_t memSize = this.capacity * Element.sizeof;
         realloc(this.elements, memSize);
     }
     void put(Element element) {
         if (this.length>= this.capacity)
             this.reAlloc();
         this.elements[this.length] = element;
         ++ this.length;
     }
     void opBinary(string op) (Element element)
     if (op == "+") {

...wait!

Did you just overload binary operator + to mean append?

Reply via email to