May 09, 2004
It seems to me that supporting the negative array index of C for the sake of backward compatibility goes against the design philosophy for D, which as I see it,  is the keeping of the general look and feel of C++ while discarding dubious features of which -ve array indexing is surely one?  Wouldn't it make sense to remove this dangerous behaviour from the language, or better to replace it with an alternative meaning. Besides, how many people out there actually use indexing in this way, although maybe for pointer manipulation it could be useful, albeit error prone.

Introducing a special operator ($) to denote the length strikes me as ungainly, making the code more perl-like, but perhaps that's just my dislike of none C symbols.

Has anybody given any thought to an [optional] stride value:

int[] x = a[1..10 : 2];    // Gets every other element of the array

Cheers,
Harvey.


"Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:c7d5p2$1n2f$1@digitaldaemon.com...
> To be less facetious. The reason it's a very bad idea is that array
subscripting
> in C and C++ and D can be done with signed integers because it is legal
_and
> meaningful_ to pass a -ve subscript to mean prior to the given base
(pointer
> and/or array).
>
> Since D's support of C constructs most certainly encompasses this very
important,
> albeit dangerous, construct, it would be nonsensical to have built-in D
arrays
> use a back-relative offset and pointers use -ve offset. It would be a
total
> killer.
>
> "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c7d5bc$1lsl$1@digitaldaemon.com...
> > Norbert Nemec wrote:
> >
> > >Hi there,
> > >
> > >I wonder whether this has been discussed before:
> > >
> > >* How about allowing negative array indices to count backward from the
end
> > >of the array?
> > >
> > >
> > Yes it has.
> >
> > -- 
> > -Anderson: http://badmama.com.au/~anderson/
>
>


May 10, 2004
Harvey Stroud wrote:
> It seems to me that supporting the negative array index of C for the sake of
> backward compatibility goes against the design philosophy for D, which as I
> see it,  is the keeping of the general look and feel of C++ while discarding
> dubious features of which -ve array indexing is surely one?

We already do discard this.  It's called array bounds checking.

> Wouldn't it make sense to remove this dangerous behaviour from the language, or better
> to replace it with an alternative meaning.

There would be a performance hit if we had to check at runtime if every index is +ve or -ve, wherever it can't be determined at compile time.

> Besides, how many people out there actually use indexing in this way, although maybe for pointer
> manipulation it could be useful, albeit error prone.

Well, D&DP in general is almost bound to be error prone.  But since preserving D&DP support is part of D's design strategy, perhaps it should be kept.

> Introducing a special operator ($) to denote the length strikes me as
> ungainly, making the code more perl-like, but perhaps that's just my dislike
> of none C symbols.

Do you have an idea for a nicer symbol to use for this?

> Has anybody given any thought to an [optional] stride value:
> 
> int[] x = a[1..10 : 2];    // Gets every other element of the array
<snip top of upside-down reply>

Not yet AFAIK.

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
May 10, 2004
Harvey Stroud wrote:

> It seems to me that supporting the negative array index of C for the sake of backward compatibility goes against the design philosophy for D...

For pointers, negative indices actually make sense. If you allow indexing of raw pointers (which I think is a good idea) then prohibiting negative indices would be strange. For arrays, negative indices are, of cause, caught by the range checking mechanism.

Raw pointers, of course, are error prone. Anyway it's the philosophy of D to give the developer all the tools to shoot himself in the foot, but make it clear what the dangerous tools are, and encourage him to avoid these tools completely.

> Introducing a special operator ($) to denote the length strikes me as ungainly, making the code more perl-like, but perhaps that's just my dislike of none C symbols.

That's just personal taste. $ has no meaning in D so far, and it is a plain ASCII character. Why not put it to use?

B.t.w: in the suggested meaning, $ would not be a normal operator at all, but something special that does not exist in D so far: a "zero-ary operator" or however you want to call it.

> Has anybody given any thought to an [optional] stride value:
> 
> int[] x = a[1..10 : 2];    // Gets every other element of the array

See my multidimension array proposal at

http://homepages.uni-regensburg.de/~nen10015/documents/D-multidimarray.html

it contains strided slices and much more.

May 10, 2004
Norbert Nemec wrote:

<snip>
> See my multidimension array proposal at
> 
> http://homepages.uni-regensburg.de/~nen10015/documents/D-multidimarray.html
> 
> it contains strided slices and much more.

"The former possibility to assign to the .size property of an array should be dropped since it is obscuring what actually happens:"

Did you mean .size or .length?

If .length, then I'm not sure I'd agree with you.

"upsizing on the other hand, means allocating new memory and copying the existing data. For this operation, a different syntax should be found that makes clear what is happening."

Not necessarily.  It could mean simply changing the range, filling up already allocated growing space.

The point of D isn't to have the programmer concern him/herself with the inner workings of everything.  If they wanted that, they'd probably use assembly.  Or maybe compromise with plain old C.

The idea of D is to support syntax that makes sense to the human programmer, while allowing the compiler to implement it efficiently.

        "M[a][b] = new mytype();

Be aware of the difference between the type declaration mytype[B][A] and the dereferenciation mytype[a][b]."

You mean "the dereferenciation M[a][b]"?

"In its full generality, this internal representation would, of course, allow all kinds of weird shapes and self-overlappings."

And word/dword-alignment of rows where the individual elements may be byte-aligned, if there are benefits to that.

"The property .diag() sums up all strides and returns a one-dimensional array reference corresponding to the total diagonal of the original array."

What if the array isn't square/cube/tesseract/general hypercube?  Would it just count the shortest dimension, i.e. as far as the diagonal remains inside the array?

What conversions would be allowed between multidimensional arrays and old-fashioned D linear arrays?  Even something that can be understood by third-party foreign code?

I'd also suggest running the proposal through a spellchecker at some point.

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.
May 10, 2004
Stewart Gordon wrote:

> Norbert Nemec wrote:
> 
> <snip>
>> See my multidimension array proposal at
>> 
>>
http://homepages.uni-regensburg.de/~nen10015/documents/D-multidimarray.html
>> 
>> it contains strided slices and much more.
> 
> "The former possibility to assign to the .size property of an array should be dropped since it is obscuring what actually happens:"
> 
> Did you mean .size or .length?

Of course. Sorry about that error.

> If .length, then I'm not sure I'd agree with you.
> 
> "upsizing on the other hand, means allocating new memory and copying the existing data. For this operation, a different syntax should be found that makes clear what is happening."
> 
> Not necessarily.  It could mean simply changing the range, filling up already allocated growing space.

Even worse! If, after upsizing, you don't even know whether you are referencing new space or the same as before, the whole thing gets completely uncontrollable.

The current situation is: dynamic arrays actually are references to the heap. Two arrays may reference the same portion of the heap, so changing one will change the other. Anyhow, the language does everything to obscure this fact and make it rather hard to predict, when it happens. Unless you really know the details, you will often call .dup without need, and, in the other way, you will have trouble if you trust that two arrays refer to the same space.

> The point of D isn't to have the programmer concern him/herself with the inner workings of everything.  If they wanted that, they'd probably use assembly.  Or maybe compromise with plain old C.

That is true, but I'm not talking about implementation details but about semantics. Dynamic arrays are references and behave like references. The language tries to hide this from the developer but does not do so completely, resulting in behaviour that is hard to predict and hard to understand.

> The idea of D is to support syntax that makes sense to the human programmer, while allowing the compiler to implement it efficiently.

True, but if you hide implementation details, this should be done completely. There is a semantic difference between reference and value types. Currently, dynamic arrays behave somewhere in between, making it very confusing to use them efficiently.

>          "M[a][b] = new mytype();
> 
> Be aware of the difference between the type declaration mytype[B][A] and the dereferenciation mytype[a][b]."
> 
> You mean "the dereferenciation M[a][b]"?

True, another typo.

> "The property .diag() sums up all strides and returns a one-dimensional array reference corresponding to the total diagonal of the original array."
> 
> What if the array isn't square/cube/tesseract/general hypercube?  Would it just count the shortest dimension, i.e. as far as the diagonal remains inside the array?

True, I thought about picking the smallest range. Should have said so, I guess.

> What conversions would be allowed between multidimensional arrays and old-fashioned D linear arrays?

old-fashioned D array, or "lightweight array references" as they are called in the proposal are implicitely casted to mytype[[1]] (trivially setting the stride to 1) In the other direction, a direct cast does not make sense, since the stride might be !=1. I was thinking about having mytype[[1]].dup return a mytype[] reference. This would avoid the need for another language construct. Not sure about it, yet.

> Even something that can be understood by third-party foreign code?

Conversion to Fortran arrays is already trivially possible. (A few convenience functions might make it even more comfortable.) Everything else should be easy to implement.

> I'd also suggest running the proposal through a spellchecker at some point.

Sorry - missed out on that, I guess... :-(

May 10, 2004
Norbert Nemec wrote:

>If, after upsizing, you don't even know whether you are
>referencing new space or the same as before, the whole thing gets
>completely uncontrollable.
>  
>
It won't get uncontrollable if your careful not to create persistent alias of the same memory location. You would have to do that any way you look at it.  Just because C had malloc and realloc didn't change this problem at all.  Please give a good source example of where D arrays fail you.

-- 
-Anderson: http://badmama.com.au/~anderson/
May 10, 2004
J Anderson wrote:

> Norbert Nemec wrote:
> 
>>If, after upsizing, you don't even know whether you are referencing new space or the same as before, the whole thing gets completely uncontrollable.
>> 
> It won't get uncontrollable if your careful not to create persistent alias of the same memory location. You would have to do that any way you look at it.  Just because C had malloc and realloc didn't change this problem at all.  Please give a good source example of where D arrays fail you.

What does the following routine return:

---------------------------
char myrountine(char[] input, uint param) {
        char[] strB = input;
        strB.size = param;
        input[0] = 'x';
        return strB[0];
};
---------------------------

admittedly, you will probably call strB a persistent alias and tell me to avoid it, but how would I know? The language spec sounds like: If you want to make sure your array is unique, call .dup - otherwise nothing is guaranteed. This will result in people calling .dup unnecessarily, just because they are frightened of the "nothing is guaranteed". Actually: if you don't know the implementation details, you just have to build in .dups that are probably unnecessary.

Furthermore, sometimes, you might actually be interested in having definitely aliased arrays. The language spec, though, does not give you much certainty that an implementation might not suddenly call .dup for some reason.

May 10, 2004
Norbert Nemec wrote:

>J Anderson wrote:
>
>  
>
>>Norbert Nemec wrote:
>>
>>    
>>
>>>If, after upsizing, you don't even know whether you are
>>>referencing new space or the same as before, the whole thing gets
>>>completely uncontrollable.
>>> 
>>>      
>>>
>>It won't get uncontrollable if your careful not to create persistent
>>alias of the same memory location. You would have to do that any way you
>>look at it.  Just because C had malloc and realloc didn't change this
>>problem at all.  Please give a good source example of where D arrays
>>fail you.
>>    
>>
>
>What does the following routine return:
>
>---------------------------
>char myrountine(char[] input, uint param) {
>        char[] strB = input;
>        strB.size = param;
>        input[0] = 'x';
>        return strB[0];
>};
>---------------------------
>  
>

>admittedly, you will probably call strB a persistent alias and tell me to
>avoid it, but how would I know? 
>
You've just answered your own question.

>The language spec sounds like: If you want
>to make sure your array is unique, call .dup - otherwise nothing is
>guaranteed. This will result in people calling .dup unnecessarily, just
>because they are frightened of the "nothing is guaranteed". 
>  
>
That is not true, its quite easy to learn how D arrays behave.  You only need to use dup if you want to modify a copy of the array.  That is you don't want to modify the original array. 

>Actually: if
>you don't know the implementation details, you just have to build in .dups
>that are probably unnecessary.
>
You should know what the function you call does, otherwise why call it.  Functions that modify the size of an array are generally very easy to spot and are rare (most of the array resize should be encapsulated with its own module.)

Changing the name does not help things one bit.  It's performace reasons that make arrays like this nessary.  If you want a garrenteed array positions, wrap it in a class and create something like STL's slow vector class.

>Furthermore, sometimes, you might actually be interested in having
>definitely aliased arrays. The language spec, though, does not give you
>much certainty that an implementation might not suddenly call .dup for some
>reason.
>  
>
This is a design issue.  Use pointers to the array, or wrap them in classes.

-- 
-Anderson: http://badmama.com.au/~anderson/
May 11, 2004
"Norbert Nemec" <Norbert.Nemec@gmx.de> wrote in message news:c7nj4j$218d$1@digitaldaemon.com...
> See my multidimension array proposal at
>
>
http://homepages.uni-regensburg.de/~nen10015/documents/D-multidimarray.html
>
> it contains strided slices and much more.

Could you put that into the D wiki?


May 11, 2004
Walter wrote:

> 
> "Norbert Nemec" <Norbert.Nemec@gmx.de> wrote in message news:c7nj4j$218d$1@digitaldaemon.com...
>> See my multidimension array proposal at
>>
>>
>
http://homepages.uni-regensburg.de/~nen10015/documents/D-multidimarray.html
>>
>> it contains strided slices and much more.
> 
> Could you put that into the D wiki?

I have a long list of changes and corrections I want to work in first. Stewart Gordon and Ben Hinkle gave me some very valuable input that should find its way into the the proposal. Once I'm satisfied with it and the most controversial points are solved, it is, of course, up to you, Walter, to do with it what you like.