Thread overview
opIndexAssign and ~=,+=,++, etc
Sep 11, 2004
Ben Hinkle
Sep 11, 2004
Ben Hinkle
Sep 11, 2004
Ivan Senji
Sep 11, 2004
Ben Hinkle
Sep 11, 2004
h3r3tic
Sep 11, 2004
Ivan Senji
September 11, 2004
It would be nice to somehow allow opIndexAssign to overload more than just "pure" assignment. Things like ~=, +=, ++ etc that expect any lvalue should be supported. Right now my containers support opIndexAssign but they still aren't as nice as built-in containers since they don't support all the assignment variations. Maybe opIndexAssign needs an enum of what is happening to the lvalue. The values of the enum would be Assign, AddAssign, CatAssign, etc

In other words x[y]+=10; would translate to x.opIndexAssign(AddAssign,10,y);

-Ben
September 11, 2004
Ben Hinkle wrote:

> It would be nice to somehow allow opIndexAssign to overload more than just "pure" assignment. Things like ~=, +=, ++ etc that expect any lvalue should be supported. Right now my containers support opIndexAssign but they still aren't as nice as built-in containers since they don't support all the assignment variations. Maybe opIndexAssign needs an enum of what is happening to the lvalue. The values of the enum would be Assign, AddAssign, CatAssign, etc
> 
> In other words x[y]+=10; would translate to
> x.opIndexAssign(AddAssign,10,y);
> 
> -Ben


Actually now that I think about it some more probably the better thing to do
is deprecate opIndexAssign and add opIndexLvalue with the signature
 Value* opIndexLvalue(Key index);
so that the it would be legal to pass indexing expressions to inout
parameters as well as the various assignment operators.

On a related topic I'd like to propose (as I think Kris did a while ago) that for builtin associative arrays opIndex doesn't add the key if it isn't there but opIndexLvalue does. The current behavior feels like a left-over from C++'s notion that overloaded indexing expressions return lvalues.

*OR* we can do what C++ does and just have one opIndex that returns a pointer and forget about having two overloadable versions of indexing.

-Ben
September 11, 2004
"Ben Hinkle" <bhinkle4@juno.com> wrote in message news:chv2pj$2sln$1@digitaldaemon.com...
> It would be nice to somehow allow opIndexAssign to overload more than just "pure" assignment. Things like ~=, +=, ++ etc that expect any lvalue
should
> be supported. Right now my containers support opIndexAssign but they still aren't as nice as built-in containers since they don't support all the assignment variations. Maybe opIndexAssign needs an enum of what is happening to the lvalue. The values of the enum would be Assign,
AddAssign,
> CatAssign, etc
>

It would be nice. But it is a problem to have special cases for lvalue and
not lvalue
(opIndex, opIndexAssign and other pairs)
If we could only return lvalues :) all problems like this would be solved...
class A
{
    int x;
    inout int X(){return x;}
}

There would no longer be a need for inventing *Assign functions.

> In other words x[y]+=10; would translate to
x.opIndexAssign(AddAssign,10,y);
>
> -Ben


September 11, 2004
Ivan Senji wrote:

> "Ben Hinkle" <bhinkle4@juno.com> wrote in message news:chv2pj$2sln$1@digitaldaemon.com...
>> It would be nice to somehow allow opIndexAssign to overload more than just "pure" assignment. Things like ~=, +=, ++ etc that expect any lvalue
> should
>> be supported. Right now my containers support opIndexAssign but they still aren't as nice as built-in containers since they don't support all the assignment variations. Maybe opIndexAssign needs an enum of what is happening to the lvalue. The values of the enum would be Assign,
> AddAssign,
>> CatAssign, etc
>>
> 
> It would be nice. But it is a problem to have special cases for lvalue and
> not lvalue
> (opIndex, opIndexAssign and other pairs)
> If we could only return lvalues :) all problems like this would be
> solved... class A
> {
>     int x;
>     inout int X(){return x;}
> }
> 
> There would no longer be a need for inventing *Assign functions.

Oh yeah - I forgot about all those regular *Assign functions. Plus we'll
eventually need to be able to overload slice assignment to mimic the
builtin behavior for things like
 x[0..10] = 100;
(which currently works for builtins) and eventually things like
 x[0..10] += 100;
(which currently doesn't work for builtins).

So we really need three forms of *Assign overloads: regular, indexed and sliced. Since plain old opAssign doesn't exist (and would be a big decision to add) the enum solution isn't good. And since slices cover more than a single lvalue I think long-term the best solution is to just add a bazillion opFooBarAssign operators where Foo can be '','Index','Slice' and Bar can be '','Add','Sub','Mul',etc except that 'opAssign' doesn't exist.

-Ben

ps - counting up the actualy number of operators this would add comes to 24, not a bazillion.
September 11, 2004
Ivan Senji wrote:
> (...) But it is a problem to have special cases for lvalue and
> not lvalue
> (opIndex, opIndexAssign and other pairs)
> If we could only return lvalues :) all problems like this would be solved...
> class A
> {
>     int x;
>     inout int X(){return x;}
> }
> 
> There would no longer be a need for inventing *Assign functions.
> 
> 
>>In other words x[y]+=10; would translate to
> 
> x.opIndexAssign(AddAssign,10,y);
> 
>>-Ben

I agree with you completely. Returning inout would make life much easier. Heh, I imagine explaining D to some C++ dude like:
- You don't have to write all that operator<>=>=<(...), opCmp will be enough
- Wow, that's cool!
- But you have to define tons of opIndexAssignFoo where Foo can be Mul, Add Div or whatever
- Erm.... that sucks, I think I'll switch to Cobol instead

Tom
September 11, 2004
"h3r3tic" <h3r3tic@dev.null> wrote in message news:chv9oe$2vsd$1@digitaldaemon.com...
> Ivan Senji wrote:
> > (...) But it is a problem to have special cases for lvalue and
> > not lvalue
> > (opIndex, opIndexAssign and other pairs)
> > If we could only return lvalues :) all problems like this would be
solved...
> > class A
> > {
> >     int x;
> >     inout int X(){return x;}
> > }
> >
> > There would no longer be a need for inventing *Assign functions.
> >
> >
> >>In other words x[y]+=10; would translate to
> >
> > x.opIndexAssign(AddAssign,10,y);
> >
> >>-Ben
>
> I agree with you completely. Returning inout would make life much easier.

I always missed references as return types in D, it is something i like very much in C++ and they are extremly usefull!

Ben's solution with operators for every case is something that would
work and although it involves more operators, it is then easier
to distinguish between opIndex and opIndexAssign.
For example in a[x]; i may just want to return a value, and
int a[x]=y; i may wish to check if the value of y is in the right range.

This doesn't mean i wouldn't like references as return types :)

> Heh, I imagine explaining D to some C++ dude like:
> - You don't have to write all that operator<>=>=<(...), opCmp will be
enough
> - Wow, that's cool!
> - But you have to define tons of opIndexAssignFoo where Foo can be Mul,
> Add Div or whatever
> - Erm.... that sucks, I think I'll switch to Cobol instead

Cobol!? Hm! I think this guy will stay with C++ :)

>
> Tom