www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - opIndexAssign and ~=,+=,++, etc

reply Ben Hinkle <bhinkle4 juno.com> writes:
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
Sep 11 2004
next sibling parent Ben Hinkle <bhinkle4 juno.com> writes:
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
Sep 11 2004
prev sibling parent reply "Ivan Senji" <ivan.senji public.srce.hr> writes:
"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
Sep 11 2004
next sibling parent Ben Hinkle <bhinkle4 juno.com> writes:
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.
Sep 11 2004
prev sibling parent reply h3r3tic <h3r3tic dev.null> writes:
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
Sep 11 2004
parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
"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
Sep 11 2004