www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why do associative arrays return from opIndexAssign by value?

reply "TommiT" <tommitissari hotmail.com> writes:
Associative arrays return from opIndexAssign the inserted or 
existing element by value. Why don't they return it by reference, 
which would be much more useful? Maybe not very common, but 
here's an example of the kind of situation where I actually would 
have needed it:

int[string] values;

foreach (string key; keys)
{
     int* ptr = key in values;

     if (ptr == null)
     {
         // Currently cannot write this:
         // ptr = &(values[key] = initValueFor(key));

         // The workaround is inefficient:
         values[key] = initValueFor(key);
         ptr = key in values;
     }
     edit(*ptr);
}
Jun 18 2013
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 18 June 2013 at 09:03:27 UTC, TommiT wrote:
 Associative arrays return from opIndexAssign the inserted or 
 existing element by value. Why don't they return it by 
 reference, which would be much more useful? Maybe not very 
 common, but here's an example of the kind of situation where I 
 actually would have needed it:

 int[string] values;

 foreach (string key; keys)
 {
     int* ptr = key in values;

     if (ptr == null)
     {
         // Currently cannot write this:
         // ptr = &(values[key] = initValueFor(key));

         // The workaround is inefficient:
         values[key] = initValueFor(key);
         ptr = key in values;
     }
     edit(*ptr);
 }

Assignation aren't lvalues in general, so that is consistent. AA are screwed in much deeper way that that simple use case, and I do not think adding the feature right now is a wise move.
Jun 18 2013
prev sibling next sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Tuesday, 18 June 2013 at 09:07:31 UTC, deadalnix wrote:
 On Tuesday, 18 June 2013 at 09:03:27 UTC, TommiT wrote:
 Associative arrays return from opIndexAssign the inserted or 
 existing element by value. Why don't they return it by 
 reference, which would be much more useful? Maybe not very 
 common, but here's an example of the kind of situation where I 
 actually would have needed it:

 int[string] values;

 foreach (string key; keys)
 {
    int* ptr = key in values;

    if (ptr == null)
    {
        // Currently cannot write this:
        // ptr = &(values[key] = initValueFor(key));

        // The workaround is inefficient:
        values[key] = initValueFor(key);
        ptr = key in values;
    }
    edit(*ptr);
 }

Assignation aren't lvalues in general, so that is consistent.

I didn't see that coming. In C++ assignments are pretty consistently mutable lvalues. Do you know why this is so in D?
Jun 18 2013
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 18 June 2013 at 09:18:34 UTC, TommiT wrote:
 Assignation aren't lvalues in general, so that is consistent.

I didn't see that coming. In C++ assignments are pretty consistently mutable lvalues. Do you know why this is so in D?

I guess because (a = 5) = 7; isn't a really interesting thing to do. = is right associative anyway, so most of the time it makes absolutely no difference if it is an rvalue or an lvalue.
Jun 18 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, June 18, 2013 11:18:33 TommiT wrote:
 On Tuesday, 18 June 2013 at 09:07:31 UTC, deadalnix wrote:
 Assignation aren't lvalues in general, so that is consistent.

I didn't see that coming. In C++ assignments are pretty consistently mutable lvalues. Do you know why this is so in D?

Assignment operators definitely should return lvalues normally. I don't know why deadalnix would think otherwise. It's pretty much the norm in C++, and I see no reason for it to be different in D. No, it doesn't work for all types, but in the general case, it should. However, given the current state of AAs and the fact that their implementation pretty much needs to be completely redone, I'm not sure how good an idea it would be to make this work right now. Maybe it wouldn't be a big deal, and maybe it would be a very bad idea. It certainly wouldn't hurt to open an enhancement request though: http://d.puremagic.com/issues At minimum, I would think that in the long run, we would want what you're trying to do to work. - Jonathan M Davis
Jun 18 2013
prev sibling next sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Tuesday, 18 June 2013 at 09:28:04 UTC, Jonathan M Davis wrote:
 Assignment operators definitely should return lvalues normally. 
 I don't know
 why deadalnix would think otherwise. It's pretty much the norm 
 in C++, and I
 see no reason for it to be different in D. No, it doesn't work 
 for all types,
 but in the general case, it should.

At least int assignment isn't lvalue. I find this quite surprising: void edit(ref int) { } void main() { int n; //edit(n = 4); // Error edit(n += 4); }
Jun 18 2013
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 18 June 2013 at 09:28:04 UTC, Jonathan M Davis wrote:
 On Tuesday, June 18, 2013 11:18:33 TommiT wrote:
 On Tuesday, 18 June 2013 at 09:07:31 UTC, deadalnix wrote:
 Assignation aren't lvalues in general, so that is consistent.

I didn't see that coming. In C++ assignments are pretty consistently mutable lvalues. Do you know why this is so in D?

Assignment operators definitely should return lvalues normally. I don't know why deadalnix would think otherwise. It's pretty much the norm in C++, and I see no reason for it to be different in D. No, it doesn't work for all types, but in the general case, it should.

I have no opinion on the subject. Simply stating facts about D right now.
Jun 18 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, June 18, 2013 11:41:03 TommiT wrote:
 On Tuesday, 18 June 2013 at 09:28:04 UTC, Jonathan M Davis wrote:
 Assignment operators definitely should return lvalues normally.
 I don't know
 why deadalnix would think otherwise. It's pretty much the norm
 in C++, and I
 see no reason for it to be different in D. No, it doesn't work
 for all types,
 but in the general case, it should.

At least int assignment isn't lvalue. I find this quite surprising: void edit(ref int) { } void main() { int n; //edit(n = 4); // Error edit(n += 4); }

Maybe that's by design, but it's not what I would have expected. I don't know if that's a bug or not. Certainly, it doesn't match how it works in C++, and I don't know why D would be any different in this regard. - Jonathan M Davis
Jun 18 2013
prev sibling next sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Tuesday, 18 June 2013 at 10:18:23 UTC, Jonathan M Davis wrote:
 On Tuesday, June 18, 2013 11:41:03 TommiT wrote:
 At least int assignment isn't lvalue. I find this quite
 surprising:
 
 void edit(ref int) { }
 
 void main()
 {
      int n;
      //edit(n = 4); // Error
      edit(n += 4);
 }

Maybe that's by design, but it's not what I would have expected. I don't know if that's a bug or not. Certainly, it doesn't match how it works in C++, and I don't know why D would be any different in this regard. - Jonathan M Davis

This must be by design, because associative arrays return lvalue from += operator as well: int[string] values; foreach (string key; keys) { int* ptr = key in values; if (ptr == null) { // Now it's quite a decent workaround: ptr = &(values[key] += 0); *ptr = initValueFor(key); } edit(*ptr); }
Jun 18 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, June 18, 2013 12:35:06 TommiT wrote:
 On Tuesday, 18 June 2013 at 10:18:23 UTC, Jonathan M Davis wrote:
 On Tuesday, June 18, 2013 11:41:03 TommiT wrote:
 At least int assignment isn't lvalue. I find this quite
 surprising:
 
 void edit(ref int) { }
 
 void main()
 {
 
      int n;
      //edit(n = 4); // Error
      edit(n += 4);
 
 }

Maybe that's by design, but it's not what I would have expected. I don't know if that's a bug or not. Certainly, it doesn't match how it works in C++, and I don't know why D would be any different in this regard. - Jonathan M Davis

This must be by design, because associative arrays return lvalue from += operator as well:

Well, it's also the sort of thing that a lot of people screw up even in C++ - they make operater= return void when it should return a reference to the object being assigned to. So, it wouldn't entirely surprise me if it's the way that it is with AAs, because the person coding them up forgot to do otherwise. What's surprises me more is ints, but regardless of whether it's by design by not (and there's a decent chance that it is), I'd argue that it was a poor decision unless there's something that I'm missing. In any case, I think that it's worth opening up an enhancement request. - Jonathan M Davis
Jun 18 2013
prev sibling parent "TommiT" <tommitissari hotmail.com> writes:
On Tuesday, 18 June 2013 at 10:43:58 UTC, Jonathan M Davis wrote:
 On Tuesday, June 18, 2013 12:35:06 TommiT wrote:
 This must be by design, because associative arrays return 
 lvalue
 from += operator as well:

Well, it's also the sort of thing that a lot of people screw up even in C++ - they make operater= return void when it should return a reference to the object being assigned to. So, it wouldn't entirely surprise me if it's the way that it is with AAs, because the person coding them up forgot to do otherwise. What's surprises me more is ints, but regardless of whether it's by design by not (and there's a decent chance that it is), I'd argue that it was a poor decision unless there's something that I'm missing. In any case, I think that it's worth opening up an enhancement request. - Jonathan M Davis

I posted an enhancement request just get some kind of an answer to this thing: http://d.puremagic.com/issues/show_bug.cgi?id=10428
Jun 20 2013