September 06, 2001

Walter wrote:
> 
> "Russell Borogove" <kaleja@estarcion.com> wrote in message news:3B97D5B9.9FF40BD7@estarcion.com...
> > I think I'm in favor. Is there any other way to resize an array already provided?
> 
> The current way is to new a new array and copy the contents of the old one.

There are cases where you have a very large array in an "unpacked" or otherwise wasteful format, and you want to convert the data in place to a more compact format. In this case, if you have to create a new array and compact-on-copy, you might be spending more memory than you want to in the intermediate case. (Obviously, to make this work, your data-typing has to be fairly weak.) With a truncating resize, you can get through a memory-tight situation that you can't survive otherwise.

> Such always seemed like too much fiddling to me, and fiddling code is just more code that harbors bugs. The three choices are:
> 
>     array.length = newlength;
> 
>     array = renew(array, newlength, array[0].size);
> 
>     array.setLength(newlength);
> 
> I am leaning towards the first because it is simpler and so less prone to bugs. What I don't like about it is it appears to be a simple assignment, but is not.

*nod*

Russ Lewis wrote:
> 
> 4th option:
> array.append(int[10]);

But this doesn't offer a truncation semantic.

-RB
September 06, 2001
Russ Lewis wrote:

> Charles Hixson wrote:
> 
> 
>>Are you resizing the array, or just changing the length of it
>>that is counted as filled?  If you are resizing the array, then
>>I don't like that syntax.  It seems to imply that what you are
>>doing is taking a string, and then saying "I'm interested in
>>*this* much of it".  I.e., it implies that all that you are
>>doing is changing a variable.  If this includes an implicit
>>resize and potentially string copying and garbage collection,
>>then it seems to be to be the wrong syntax.  On the other hand,
>>it would frequently be nice to take a block of text and say
>>"this variable represents 20 characters starting at character
>>97".  (But this doesn't seem to be what D strings are.  Pity.
>>Could you consider string range variables?)
>>
> 
> If you are trying to get a substring of a string, just use this syntax:
> 
> char[] longString = /*some code that creates a long string*/;
> char[] subString = longString[97..116]; /* contains 20 characters of the other
> string */
> 
> This (in cooperation with garbage collection) is going to be *really* nice for
> regular expressions.  You can just return a dynamic array that is a subset of
> another string.  Since strings are not null terminated in D, no copying is
> needed!
> 
> 

I was actually talking about using a substring *without* taking it out of the string.  Sort of a safe version of C's pointer to char variable.  You might be able to declare that:
char [] inline;
declare inline [1,15] user_id;
declare inline [16, 29] first_name;
declare inline [35, 50] last_name;
declare inline [16, 60] full_name;
...

This would be read-only access within a routine, and could only be passed as a parameter with copy semantics (which would negate much of the benefit), but it could be quite useful in making code easier to read without requiring excessive string copying.  Or perhaps an optimizer could avoid the extra string copies. I don't know.  But from my simple view it would be easier to read in a record as a string with (overlapping) fields defined on it, and then operate on those.  This would let one say something like:
the_name = trim (last_name) + ", " + trim (first_name)

rather than the equivalent
the_name = trim (substring(inline, 35, 15) ) + ", " + trim (substring(inline, 1, 15) )

One could, of course have defined intermediate variables, but then one would be doing an extra copy for each field for each record (unless an optimizer could decide that the extra copy wasn't needed without being told).

September 06, 2001
Oh, certainly, no doubt would dynamic arrays as the spec described and as we're ironing out here be INCREDIBLY useful.  I think the question that started this thread, however, and a concern of mine would be how do you resize the array?  Is it by changing a variable such as ".length", or should it be by calling some function?

Once again, forgive my ignorance to the ways of compilers and languages and such, but how can the code know that the instant the variable gets a new value, realloc() style stuff should be done on the array?

Isn't a function more in order?

int[] array1 = {3,3,3};        // at this point, any references to
array1.length will return 3, but it's a read only variable
array1.resize( 10 );   // array1.length will now be 10 and indices 0, 1, and
2 are 3, 3-9 are 0.
array1.resize( 2 );   // array1.length will now be 2, indices 2-9 are lost


-Brady

>
> Arrays are *such* a basic data structure, I feel that a great deal is
gained
> by building resizable arrays into the language as a primitive. A lot of my code deals with arrays, and all the fiddling to manage their memory eats
up
> much of my time and is lots of code that has bug potential. My experiments show that using D dynamic arrays cleans up a lot of code. Things just get
a
> lot simpler, with no sacrifice in performance.
>



September 06, 2001
Charles Hixson wrote:

> I was actually talking about using a substring *without* taking
> it out of the string.  Sort of a safe version of C's pointer to
> char variable.  You might be able to declare that:
> char [] inline;
> declare inline [1,15] user_id;
> declare inline [16, 29] first_name;
> declare inline [35, 50] last_name;
> declare inline [16, 60] full_name;
> ...

Right, my understanding is that you could do the following:

void foo(char[] data)  // data is passed by reference, NOT value
{
   char[] user_id = data[1..15];
   char[] first_name = data[16..29];
   char[] last_name = data[35..50];
   char[] full_name = data[16..60];

   user_id = data[1..15];
   first_name = data[16..29];
   last_name = data[35..50];
   full_name = data[16..60];
   ...
};

As I understand it, none of this does any string copying.  All of the field arrays point into the main array (and, BTW, count as references to the main array - so you won't get garbage collected at the wrong time).

> the_name = trim (last_name) + ", " + trim (first_name)

Similarly, the beauty of D dynamic arrays is that the trim function can return an array that points into the original argument but has a different length.  Once it is used in the concatenation process, that reference to the array goes away automagically....

September 06, 2001
I just spoke on this one in a different part of this thread.  The first one does have a nice simplicity to it, but I would be concerned to stay away from it for the very reason you say - it looks like a simple assignment when it's really not.

I vote for 3 (though in my other response the function name I chose was
'resize( newlength )' )

-Brady

>
> The current way is to new a new array and copy the contents of the old
one.
> Such always seemed like too much fiddling to me, and fiddling code is just more code that harbors bugs. The three choices are:
>
>     array.length = newlength;
>
>     array = renew(array, newlength, array[0].size);
>
>     array.setLength(newlength);
>
> I am leaning towards the first because it is simpler and so less prone to bugs. What I don't like about it is it appears to be a simple assignment, but is not.
>
>


September 06, 2001
Walter wrote:

> "Russell Borogove" <kaleja@estarcion.com> wrote in message
> news:3B97D5B9.9FF40BD7@estarcion.com...
> 
>>Walter wrote:
>>
>>>I've gone back and forth on this issue (whether setting .length resizes
>>>
> the
> 
>>>array, or is it read-only). What do y'all think?
>>>
>>I think I'm in favor. Is there any other way to resize an array
>>already provided?
>>
>>-RB
>>
> 
> The current way is to new a new array and copy the contents of the old one.
> Such always seemed like too much fiddling to me, and fiddling code is just
> more code that harbors bugs. The three choices are:
> 
>     array.length = newlength;
> 
>     array = renew(array, newlength, array[0].size);
> 
>     array.setLength(newlength);
> 
> I am leaning towards the first because it is simpler and so less prone to
> bugs. What I don't like about it is it appears to be a simple assignment,
> but is not.
> 
> 
> 

I would prefer: array.setLength(newLength);

This is clearly a method call.  The first choice looks to me like you are adjusting a variable that says how much of it you are using, and this isn't what you mean (though it might be nice to have such a value...size?  [I would have choosen length to mean that, but size is a good alternative, and they mean about the same].  Possibly contains?  Or cells_used?  That is one that it would make sense to have with variable semantics, since all that it is is an internal variable.

my second choice would be:
array = array.asSize(newSize);

This syntax makes it clear that a copy of the array is being done.  I just don't like the name, and haven't been able to think of a decent on that makes the function clear.  Again, this is clearly a method call.  Possibly the name could be "copyWithSize", but that isn't a good choice if it's the only way to do it.  It's too long a name for such a common operation.

September 06, 2001
Bradeeoh wrote:

> Isn't a function more in order?
>
> int[] array1 = {3,3,3};        // at this point, any references to
> array1.length will return 3, but it's a read only variable
> array1.resize( 10 );   // array1.length will now be 10 and indices 0, 1, and
> 2 are 3, 3-9 are 0.
> array1.resize( 2 );   // array1.length will now be 2, indices 2-9 are lost

Somebody, earlier in this thread, made a passing reference that setting .length is like using a gettor; what looks like setting a simple parameter actually expands to a function call.  So, to use your syntax, it would work like:

array1.length = 10; /* internally, what happens is array1.resize(10); */

September 06, 2001
Charles Hixson wrote:

> This is clearly a method call.  The first choice looks to me like you are adjusting a variable that says how much of it you are using, and this isn't what you mean (though it might be nice to have such a value...size?

size would be a good choice, but it's already a parameter that works a lot like a dynamic sizeof:

int[] array = {3,4,5};
int len = array.length; /* returns 3 */
int size = array.size; /* returns 12, if you assume 32bit ints */

September 07, 2001
	A lot of people seem to think a lot of things.  I think the question
got over interpreted.  Walter, would it be safe to say that dynamic
arrays are not like other languages' Vector classes or script languages'
dynamic arrays?  Specifically in that D's dynamic arrays don't try to
provide enhanced appending, prepending, truncation, splicing or manage
how much space is allocated vs. used?
	Perhaps it would be safer for folks to think of a dynamic array in D as
a C dynamically allocated array that knows how much space it has
allocated?  Given that, it might be nice to have resizing done with a
property.  A method is apparently making people think that this is a
class with all sorts of nice features that it is not supposed to
provide.  Instead it is a basic type that abstracts way a very common
and error prone operation, realloc, so you can implement all of these
other wonderful abstractions with less worry.  Of course since realloc
is definitely an operation and not a trivial one, it would imply a
method would be the way to go.  How am I doing so far?
	In the end, property or method, I don't really care.  I guess I would
like the syntax that uses less typing, since I'm comfortable with the
operation that's happening.  I'm content with either, but I do think
that this thread has gone overboard with great expectations for a very
simple type & abstraction.  Are my expectation too low for what was
intended of the dynamic array?

	I would like a syntax that could do a resize in-place since the runtime
memory management system could probably do it when space allows.
(Realloc works this way on most systems, right?)  Forcing a reassignment
would almost guarantee a copy whether or not it was really needed.
Also, I would assume that any resize operation could potentially throw
an exception.  If so, then that should probably be considered with
respect to the whole exception specification issue.

	I guess I'll take the opportunity to provide another nudge for some
form of overloading while I'm at it.  If in fact D's dynamic arrays are
meant to be merely the primitive used to create these other spectacular
container types that people clamor for, it would be nice if the higher
level containers could have a square brace operator.

Dan


Walter wrote:
> 
> I've gone back and forth on this issue (whether setting .length resizes the array, or is it read-only). What do y'all think?
> 
> Russ Lewis wrote in message <3B96A34F.DABE45E5@deming-os.org>...
> >I'm assuming that the .length property of a dynamic array can be set, causing the code to change the size, right?  This is not specified in the spec, that I can see.
> >
> >Also, I assume that such a resize operation can (if expanding) result in an out-of-memory exception being thrown, just like operator new.  I don't see specs for either of those...
> >
September 07, 2001
Russ Lewis wrote in message <3B980568.6E0E71EC@deming-os.org>...
>size would be a good choice, but it's already a parameter that works a lot
like a
>dynamic sizeof:
>int[] array = {3,4,5};
>int len = array.length; /* returns 3 */
>int size = array.size; /* returns 12, if you assume 32bit ints */


Actually, no, .size returns 8 for arrays. The reason is because that's how much storage the reference takes up. .size doesn't refer to how much space the actual data in the array consumes.

The reason it is this way is so you can sum the .size's of, say, a struct's members and arrive at the .size of the struct (assuming 1 byte alignment). Doing otherwise would lead to ambiguities, like what would the .size be for an array of arrays?

To get the size of the data bytes in the array:

    array.length * array[0].size