Thread overview
Operator overloading for array indexing and slicing.
Jan 23, 2003
Patrick Down
Jan 23, 2003
Walter
Jan 23, 2003
Patrick Down
Jan 24, 2003
Burton Radons
Jan 24, 2003
Patrick Down
Mar 06, 2003
Walter
Mar 06, 2003
Burton Radons
Mar 06, 2003
Mike Wynn
Jan 24, 2003
Antti Sykari
January 23, 2003
http://www.digitalmars.com/d/future.html

Walter, I noticed in the future document that you are going to add operator overloading for array indexing and slicing.

I hope that you will consider doing separate "get index" and "set index" operations.

class Foo
{
int getidx(int index)
{
//...
}

Foo setidx(int index, int value)
{
//...
}
}


January 23, 2003
Why? I was thinking of the index function returning a pointer, which can then be used as either an lvalue or an rvalue.

"Patrick Down" <Patrick_member@pathlink.com> wrote in message news:b0p40t$2q81$1@digitaldaemon.com...
>
> http://www.digitalmars.com/d/future.html
>
> Walter, I noticed in the future document that you are going to add operator overloading for array indexing and slicing.
>
> I hope that you will consider doing separate "get index" and "set index" operations.
>
> class Foo
> {
> int getidx(int index)
> {
> //...
> }
>
> Foo setidx(int index, int value)
> {
> //...
> }
> }
>
>


January 23, 2003
The pointer approach does not let you do any checking or processing of the value being assigned.


In article <b0pm6a$3o8$1@digitaldaemon.com>, Walter says...
>
>Why? I was thinking of the index function returning a pointer, which can then be used as either an lvalue or an rvalue.
>
>"Patrick Down" <Patrick_member@pathlink.com> wrote in message news:b0p40t$2q81$1@digitaldaemon.com...
>>
>> http://www.digitalmars.com/d/future.html
>>
>> Walter, I noticed in the future document that you are going to add operator overloading for array indexing and slicing.
>>
>> I hope that you will consider doing separate "get index" and "set index" operations.
>>
>> class Foo
>> {
>> int getidx(int index)
>> {
>> //...
>> }
>>
>> Foo setidx(int index, int value)
>> {
>> //...
>> }
>> }
>>
>>
>
>


January 24, 2003

Patrick Down wrote:
> In article <b0pm6a$3o8$1@digitaldaemon.com>, Walter says...
>
>>Why? I was thinking of the index function returning a pointer, which can
>>then be used as either an lvalue or an rvalue.
>
> The pointer approach does not let you do any checking or
> processing of the value being assigned.

Whoa, I hadn't thought that Walter might do that.  Yes, both get and set are needed or you can't do many things.  For example:

- You might return zero when the user reads out-of-range of an array but resize the array if he assigns to it (like how the associative arrays work).

- Insertion into the array might cause some simple refcounting to be done, or require further registration.

- The actual accepted values of the array may be more limited than what the public interface allows.  IOW, DBC is needed.

- If you return a static zero pointer from the array index while trying to do something like the first item here, it could easily get modified and you would have no way to control that.  By the time you can report it as an error, the guilty code will have been long gone.

- The array might be entirely ephemeral, with values extrapolated at runtime.  The assignment might not be a valid pointer by the time the user tries to do so.

- The array might be shared and require a synchronized block to assign properly, or go through conflict resolution.

All of these problems are easily handled by separate getitem and setitem methods.  C++ made a mistake thinking it could be so simple.

This would also be a good opportunity to start allowing user-handled rectangular arrays.  I don't want the language to support them.  I just want:

    x [a, b];

To be turned into:

    x.getitem (a, b);

For slices, I think we need to bite the bullet and go with:

    struct Range
    {
        int start;
        int end;
        bit startImplicit;
        bit endImplicit;
    }

    x [a .. b, c];

    x.getslice ((Range) [{a, b, false, false}, {c, c, false, false}]);

January 24, 2003
Burton Radons <loth@users.sourceforge.net> wrote in news:3E30C5D9.9070500@users.sourceforge.net:

> 
> 
> Patrick Down wrote:
> > In article <b0pm6a$3o8$1@digitaldaemon.com>, Walter says...
> >
> >>Why? I was thinking of the index function returning a pointer, which can then be used as either an lvalue or an rvalue.
> >
>> The pointer approach does not let you do any checking or processing of the value being assigned.
> 
> Whoa, I hadn't thought that Walter might do that.  Yes, both get and set are needed or you can't do many things.  For example:
[snip]

Yes, those are all good reasons.  In C++ you have to have operator[] return an intermediate helper class to accomplish any of those tasks.

> 
> This would also be a good opportunity to start allowing user-handled rectangular arrays.  I don't want the language to support them.  I just want:
> 
>      x [a, b];

I really like this syntax better than dealing with
arrays of arrays.
January 24, 2003
"Patrick Down" <Patrick_member@pathlink.com> wrote in message news:b0p40t$2q81$1@digitaldaemon.com...
>>> I hope that you will consider doing separate "get index" and "set index" operations.
>>>
Walter says...
>>Why? I was thinking of the index function returning a pointer, which can then be used as either an lvalue or an rvalue.
Patrick Down <Patrick_member@pathlink.com> writes:
> The pointer approach does not let you do any checking or processing of the value being assigned.

On the other hand, if you can access the value only via get/set methods, you cannot pass the value via out/inout reference parameter to a function.  (Since you just cannot get the reference to that object.)  Things like += essentially act like a member function, which essentially acts like a function with one inout and one in parameter.

I think that both cases should be allowed.  Some containers would not like their parameters passed around by reference (because everyone could change them without going through setidx) and other containers would not need to worry about that.  So I propose that by default things that would support the operator [] should be able to provide:

T getidx(int index);
void setidx(int index, T value);

If that is the case, it's forbidden to pass the value by reference and things like "a[5] += 2" must be translated to "a[5] = a[5] + 2".

However, if some container likes to give uncontrolled lvalue access to its data, it can provide

T* getidx(int index);

The idea that getidx and setidx can get several parameters is nice, too.  Reminds me of good old function call operator syntax in C++.

-Antti

March 06, 2003
"Burton Radons" <loth@users.sourceforge.net> wrote in message news:3E30C5D9.9070500@users.sourceforge.net...
>
>
> Patrick Down wrote:
>  > In article <b0pm6a$3o8$1@digitaldaemon.com>, Walter says...
>  >
>  >>Why? I was thinking of the index function returning a pointer, which
can
>  >>then be used as either an lvalue or an rvalue.
>  >
> > The pointer approach does not let you do any checking or processing of the value being assigned.
>
> Whoa, I hadn't thought that Walter might do that.  Yes, both get and set are needed or you can't do many things.  For example:

But then, as Antti said, how do you support a[i] += e; ?


March 06, 2003
Walter wrote:
> "Burton Radons" <loth@users.sourceforge.net> wrote in message
> news:3E30C5D9.9070500@users.sourceforge.net...
> 
>>
>>Patrick Down wrote:
>> > In article <b0pm6a$3o8$1@digitaldaemon.com>, Walter says...
>> >
>> >>Why? I was thinking of the index function returning a pointer, which
> 
> can
> 
>> >>then be used as either an lvalue or an rvalue.
>> >
>>
>>>The pointer approach does not let you do any checking or
>>>processing of the value being assigned.
>>
>>Whoa, I hadn't thought that Walter might do that.  Yes, both get and set
>>are needed or you can't do many things.  For example:
> 
> But then, as Antti said, how do you support a[i] += e; ?

The same way as properties:

   a.setitem(i, a.getitem(i) + e);

Although evaluating "i" and "a" but once, of course.

This does keep the index from being treated as an lvalue.  I think that's a reasonable tradeoff, considering that the C++ method makes so much else impossible.

March 06, 2003
"Walter" <walter@digitalmars.com> wrote in message news:b46udj$2tsb$1@digitaldaemon.com...
>
> "Burton Radons" <loth@users.sourceforge.net> wrote in message news:3E30C5D9.9070500@users.sourceforge.net...
> >
> >
> > Patrick Down wrote:
> >  > In article <b0pm6a$3o8$1@digitaldaemon.com>, Walter says...
> >  >
> >  >>Why? I was thinking of the index function returning a pointer, which
> can
> >  >>then be used as either an lvalue or an rvalue.
> >  >
> > > The pointer approach does not let you do any checking or processing of the value being assigned.
> >
> > Whoa, I hadn't thought that Walter might do that.  Yes, both get and set are needed or you can't do many things.  For example:
>
> But then, as Antti said, how do you support a[i] += e; ?
>

seems to me to be a good argument for a reference type, (which implicitly exists already with inout params and objects)