September 10, 2002
There's another problem:

    char[] b;
    char[] a = ...;
    b = a;
    a.length += 10;    // uh-oh, what is b[] referring to now?

(Note that this is not a memory corruption problem.)

Essentially, what you want is to guarantee that any array undergoing a resize is the only pointer into that allocated memory block.

"Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:alk6ro$1nbg$1@digitaldaemon.com...
> Maybe it should.  Which reference has the power to resize an array?  The auto reference.  The others are all slices and can't resize the array thru
a
> slice.
>
> There are so many ways to get into trouble with slices as they exist now.. resize an array out from under some slices to it, resize a slice of a
larger
> array.  I'd rather have the language guard against this.
>
> It would almost have to enter the type system to guarantee enforcement. There should be some class difference between a slice and a real array. Slices are definitely reduced functionality ... maybe dynamic array is really a special class of slice that can be resized or modified.  Writable fixed array is a slice with a write operation.  Dynamic array is a
writable
> slice that can change size as well.  Slicing an array should really obtain some kind of lock against resizing of the original array, and the slice's destructor releases that lock.
>
> Isn't a lock kinda like the opposite of a reference count?  Interesting viewpoint though... a lock will prevent the auto-destroy from deleting an object it would otherwise collect.  If everything just incremented on obtaining a reference, test-and-decremented when releasing it at scope
exit
> or before assignment, and if zero destroying it... seems simple enough at least.  Just disallow circular references.  Impossible to emulate this
kind
> of thing in D without overloading the assignment operator or copy constructor type of stuff C++ lets you do.
>
> Sean
>
> "Walter" <walter@digitalmars.com> wrote in message news:aljctp$8rt$1@digitaldaemon.com...
> >
> > "Patrick Down" <pat@codemoon.com> wrote in message news:Xns9284B5AAB7F25patcodemooncom@63.105.9.61...
> > > So let me see if I have this right. If slice size should not be changed then it leaves open the possibility that slice length can be a loop invariant. If the length is invariant then techniques like a bit flag can be used to efficiently to distinguish between arrays and slices.
> >
> > The compiler doesn't know if any random dynamic array is a slice or an original.
>
>
>


September 10, 2002
A writable array could be a subtly different type than a nonwritable one, and the check could happen during the conversion between the two types.

int[1000] a;
int[] b = a; // slice or reference
// at this point a and b point to the same memory.
// Neither a nor b is resizable so long as there's more than one active
reference.
for (a[])
    a[] = 0; // fill with zeros
// copy happens here as b transitions from normal slice to writable slice
for (b[])
    b[]++; // fill with ones
// now a is an array of 1000 zeros and b is an array of 1000 ones.

Wierd syntax, but kinda cool.  Terse.  How often do you refer to the same thing by more than one name?  And if you do, you *really* want the compiler to manage it for you, to make sure you get it right.  I'd way rather the language be safe than fast, and coming from me I can assure you that means alot.  It hurts to say it but it's true.  It doesn't do anyone any good to go 2000 MPH if it's straight toward a cliff.

Sean

"Walter" <walter@digitalmars.com> wrote in message news:alk4qv$1jnq$3@digitaldaemon.com...
>
> "Pavel Minayev" <evilone@omen.ru> wrote in message news:aljvp8$1drj$1@digitaldaemon.com...
> > Walter wrote:
> >
> > > Copy-on-write for arrays would be really cool, but I think it would
need
> > > hardware support.
> >
> > Strings in Delphi use copy-on-write without any special hardware. =) And strings are just arrays of characters...
>
> What's the performance like on:
>
>     for (i = 0; i < 1000; i++)
>         a[i] = 'c';
>
> Would that copy the array 1000 times?



September 10, 2002
"Walter" <walter@digitalmars.com> wrote in news:alk7l3$1oc8$1 @digitaldaemon.com:

> 
> "Patrick Down" <pat@codemoon.com> wrote in message news:Xns9284D2EE6549Dpatcodemooncom@63.105.9.61...
>> How does this solve the problem?
> 
> It can be resized in place, rather than by copying.

In order to resize an array in place you need to
know how much extra capacity is beyond the current
length of the array.  Do you have a way of finding
out the extra capacity for an array?
September 10, 2002
Walter wrote:

> What's the performance like on:
> 
>     for (i = 0; i < 1000; i++)
>         a[i] = 'c';
> 
> Would that copy the array 1000 times?

Nope. It uses reference counting, and does a copy only if a single string is referenced twice or more.

By the way, when I was writing my own BASIC, I first ignored copy-on-write completely. Later, it turned out that it was a major source of slowdown (mostly when string was function argument). Then I implemented Delphi-like reference counted copy-on-write... the result was about 30% speedup for most programs (and for some it was like 70%)!

September 10, 2002
Walter wrote:

> There's another problem:
> 
>     char[] b;
>     char[] a = ...;
>     b = a;
>     a.length += 10;    // uh-oh, what is b[] referring to now?

a should be copied here, so b and a would become two different arrays.

September 10, 2002
"Sean L. Palmer" <seanpalmer@earthlink.net> wrote in message news:alk8ub$1pna$1@digitaldaemon.com...
> Wierd syntax, but kinda cool.  Terse.  How often do you refer to the same thing by more than one name?  And if you do, you *really* want the
compiler
> to manage it for you, to make sure you get it right.  I'd way rather the language be safe than fast, and coming from me I can assure you that means alot.  It hurts to say it but it's true.  It doesn't do anyone any good to go 2000 MPH if it's straight toward a cliff.

I've been thinking that maybe the answer is like array bounds checking - additional checks that can be turned off for the release version.


September 10, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:alkro8$2g4b$1@digitaldaemon.com...
> Walter wrote:
> > What's the performance like on:
> >
> >     for (i = 0; i < 1000; i++)
> >         a[i] = 'c';
> >
> > Would that copy the array 1000 times?
> Nope. It uses reference counting, and does a copy only if a single string is referenced twice or more.

Ok, I see. That is the right semantics if you're doing copy on write.


September 11, 2002
On Mon, 9 Sep 2002 23:04:48 -0700, "Walter" <walter@digitalmars.com> wrote:
> 
> "Pavel Minayev" <evilone@omen.ru> wrote in message news:aljvp8$1drj$1@digitaldaemon.com...
> > Walter wrote:
> >
> > > Copy-on-write for arrays would be really cool, but I think it would need hardware support.
> >
> > Strings in Delphi use copy-on-write without any special hardware. =) And strings are just arrays of characters...
> 
> What's the performance like on:
> 
>     for (i = 0; i < 1000; i++)
>         a[i] = 'c';
> 
> Would that copy the array 1000 times?
> 

Couldn't resist the challenge :)

With respect to Euphoria, it wouldn't copy the array because nothing else is referencing it.

I tested the speed and with a 1000 iterations of the above code I got 0.05 seconds. So I doctored it to force referencing, thus...
---
sequence a,b,c
atom e
-- Create a 100 element array, zero-filled.
b = repeat(0, 100)
-- start the timer.
e = time()
-- repeat the test 1000 times
for q = 1 to 1000 do

-- Test begins--
    -- Deallocate an array
    a = {}
    -- Append 1000 items, thus growing the array each time.
    for i = 1 to 1000 do
        -- Each item is an array of 98 elements sliced from 'b'
        a = append(a,b[2..99])
        -- copy (reference) the new element
        c = a[i]
        -- change it's 1st element, thus forcing a physical copy.
        c[1] = 'c'
    end for
end for
-- stop the timer and print the duration.
printf(1, "%f\n", time()-e)

----
This took 4.06 seconds.

When I commented out the "c[1] = 'c'" line, it took 3.08 seconds.

Euphoria is an interpreted language, so I would expect much better times if this strategy was used in D.

--------------
cheers,
Derek Parnell


September 11, 2002
"Patrick Down" <pat@codemoon.com> wrote in message news:Xns92855730266AApatcodemooncom@63.105.9.61...
> In order to resize an array in place you need to
> know how much extra capacity is beyond the current
> length of the array.  Do you have a way of finding
> out the extra capacity for an array?

Yes. The garbage collector can figure it out. See the file \dmd\src\phobos\gc2\gcx.d, and look at the capacity() function.


September 11, 2002
"Walter" <walter@digitalmars.com> wrote in news:almj8h$1k8u$2 @digitaldaemon.com:
>> length of the array.  Do you have a way of finding
>> out the extra capacity for an array?
> 
> Yes. The garbage collector can figure it out. See the file \dmd\src\phobos\gc2\gcx.d, and look at the capacity() function.

Thanks, that was the missing part of the puzzle for me.