Walter Bright írta:
The purpose of T[new] was to solve the problems T[] had with passing T[]
to a function and then the function resizes the T[]. What happens with
the original?
I've tried to follow the T[], T[new], T+slice discussion, but i'm lost,
I don't think if it's a good idea, to extend the language with all kind
of decorated version of the same object ( scope (*T)[scope new][1..$] :) )
"It will tell you for instance how to describe something that was about
to happen to you in the past before you avoided it by time-jumping
forward two days in order to avoid it. The event will be described
differently according to whether you are talking about it from the
standpoint of your own natural time, from a time in the further future,
or a time in the further past and is further complicated by the
possibility of conducting conversations whilst you are actually
travelling from one time to another with the intention of becoming your
own father or mother." Douglas Adams - The Hitchhiker's Guide to the Galaxy
Just an idea to simplify this whole thing, maybe it's whole wrong, but
who knows... :)
Instead of creating new types of arrays we have already two: static and
dynamic. A dynamic version can be resized (restructured) any time, the
static has a fixed size, thus the dynamic version works as a class and
the static version works as a struct for either in,out,ref/etc.
To create slices, slices those references the whole array i'd introduce
a new type (as there is something like this): range!(T). A range is
actually an inner class of the array implementing an IRange(T) interface
with the usual popFront, front, etc. For a general class if one wants to
add range, he just have to provide an onRange (onSlice) function.
As the range interface itself provides the opIndex, opAssign, opXAssign
etc., they can be implemented as desired and no more opSliceAddAssign
and other decorated function's are required. Even more as the range is
an inner class of the array (and knows about the array), a finer tune of
what_shall_happen_when_my_referrer_array_is_resize policy can be created.
As the range itself can work as an array, range[1] (or maybe even
rang[1..2], calling the IRange!(T).onRange() ) it can be used as an
array whose structure (length) cannot be altered as desired for T[]
ex:
T[] a; // is a dynamic array as before
range(T) s1 = T[1..2]; // the slice from 1..2
range(T) s1 = T.opRange(); // the slice representing the whole range
foo( T[new] a ) is same as foo( T[] )
foo( T[] ) would be replaced by foo( range(T) ) and thus cannot be resized
furthermore
foreach( a; array )
translates to something like ->
foreach( a; a.onRange() )...
foreach( a; array[1..2] )
translates to something like ->
foreach( a; a.onRange(1,2) )...
foreach( a; array[1..2,3..4] )
translates to something like ->
foreach( a; a.onRange(1,2,3,4) )...
array[1..2] += 1
translates to something like ->
array.onRange(1,2).opAddAssign(1);
It'd be also great to create more then one onRange implementation of a
class ex: matrix.opRangeRowWise matrix.opRangeColumnWise, but i don't
know how to select the appropriate one in a foreach loop "automatically":
foreach( a; mx.rowWise ) ->
mx.selectRange(name : string) { mixin( "onRange" ~ name ) }
foreach( a; ma.selectRange("rowWise")(1,2) )...
As a conclusion: please don't create any more array type, we have just
enough. We have already all the features in the language to express both
the desired and explained (above) behaviour. Only the syntax should be
cleared out. Using the same notation multiple times with small
decorations is not a good idea, and makes things confusing.
Thanks.