www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3188] New: remove opIndexAssign from the language

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188

           Summary: remove opIndexAssign from the language
           Product: D
           Version: 2.031
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: k-foley onu.edu


Despite being redundant, my main gripe with opIndexAssign is that it can even
get in the way. For instance:

---

import std.stdio;

struct Arr(size_t W, size_t H, T)
{
    T[W * H] arr;

    this(T[W*H] rhs)
    {
        arr = rhs;
    }

    ref T opIndex(size_t row, size_t col)
    {
        return arr[row + W*col];
    }
}

int main()
{
    auto a = Arr!(2, 2, int)( [1, 2, 3, 4] );

    writeln( "a[1, 1] = ", a[1, 1] ); // a[1, 1] = 4

    a[1, 1] += 2;
    writeln( "a[1, 1] = ", a[1, 1] ); // a[1, 1] = 6

    // This requires opIndexAssign, but for no good reason
    //a[1, 1] = 42;
    //writeln( "a[1, 1] = ", a[1, 1] );

    return 0;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 17 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com
           Platform|Other                       |All






 Despite being redundant, my main gripe with opIndexAssign is that it can even
 get in the way. For instance:
opIndexAssign isn't redundant, just as property setters aren't redundant.
     // This requires opIndexAssign, but for no good reason
     //a[1, 1] = 42;
Given that opIndexAssign doesn't occur in your code, removing opIndexAssign from the language isn't going to magically make this work. Here's the compiler output (DMD 2.031 Win): ---------- C:\Users\Stewart\Documents\Programming\D\Tests\bugs>dmd bz3188.d bz3188.d(28): Error: operator [] assignment overload with opIndex(i, value) illegal, use opIndexAssign(value, i) ---------- Really, the problem is that opIndex is only meant to work on op=, ++ and --, not = itself. http://www.digitalmars.com/d/2.0/operatoroverloading.html "Note: To use array index overloading with the op=, ++, or -- operators, have the opIndex function return a reference type. This reference is then used as the lvalue for those operators." The way resolving = ought to work: - first look for a matching opIndexAssign - if none, look for an opIndex with a ref return -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 17 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188






 Given that opIndexAssign doesn't occur in your code, removing opIndexAssign
 from the language isn't going to magically make this work.
I don't see why not. "a[1, 1] = 42;" should just become "a.opIndex(1, 1) = 42;" rather than do something special because the "=" is there. I am under the impression that opIndexAssign is there only because return by reference was not available at the time of designing operator overloads. But I would be satisfied with your proposed fix anyways. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 17 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188







 Given that opIndexAssign doesn't occur in your code, removing 
 opIndexAssign from the language isn't going to magically make this 
 work.
I don't see why not. "a[1, 1] = 42;" should just become "a.opIndex(1, 1) = 42;" rather than do something special because the "=" is there.
Welcome to D. The expansion of a given expression form is by no means fixed. Already an example of this is that many operators can be overloaded either by the left operand's type (using the regular op* methods) or the right operand's type (using the op*_r methods). In the same way, the existence of opIndexAssign does nothing whatsoever to prevent the compiler from expanding it to something else instead if the type in question has no opIndexAssign. And even then, that something else would have to be implemented, which is another piece of work.
 I am under the impression that opIndexAssign is there only because 
 return by reference was not available at the time of designing 
 operator overloads. 
That's one reason. The other reason is that it can do many things that a ref return can't, such as - converting the value to an internal representation - validating the set value - calling some external API to set the value - triggering side effects beyond setting the value in memory It's the exact same reason that we have properties. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 17 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188


Steven Schveighoffer <schveiguy yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schveiguy yahoo.com





12:55:21 PDT ---

 That's one reason.  The other reason is that it can do many things that a ref
 return can't, such as
 - converting the value to an internal representation
 - validating the set value
 - calling some external API to set the value
 - triggering side effects beyond setting the value in memory
All of these things are doable from a returned struct which contains opAssign. I agree with the reporter that opIndexAssign is a feature that we could do without, although you are correct in that removing opIndexAssign doesn't solve his problem. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 17 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188







 Welcome to D.
Thank you :)
 In the same way, the existence of
 opIndexAssign does nothing whatsoever to prevent the compiler from expanding it
 to something else instead if the type in question has no opIndexAssign.
What else could it be?
 I am under the impression that opIndexAssign is there only because 
 return by reference was not available at the time of designing 
 operator overloads. 
That's one reason. The other reason is that it can do many things that a ref return can't, such as - converting the value to an internal representation - validating the set value - calling some external API to set the value - triggering side effects beyond setting the value in memory It's the exact same reason that we have properties.
But properties are not operators. If opIndexAssign must exist, then why doesn't, for example, opStarAssign also exist? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 17 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188








 In the same way, the existence of opIndexAssign does nothing 
 whatsoever to prevent the compiler from expanding it to something 
 else instead if the type in question has no opIndexAssign.
What else could it be?
The opIndex with ref return already being talked about, of course.
 But properties are not operators.  If opIndexAssign must exist, 
 then why doesn't, for example, opStarAssign also exist?
To be honest, I'm not sure either. Aside from the fact that "star" doesn't describe the semantics of any D operator, at least it would enable bit pointers that use the same notation as normal pointers. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 25 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188






PDT ---
opMulAssign exists and return by ref was meant to solve an unrelated problem, I
believe. It's not a replacement for assign operators.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 27 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188


Witold Baryluk <baryluk smp.if.uj.edu.pl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |baryluk smp.if.uj.edu.pl





04:52:22 PDT ---
I just want to comment about this controversial issue. I'm using opAssignIndex,
and in any way changing it to opIndex + ref return, will make my code
impossible to write or very slow. opIndex and opAssignIndex isn't only usefull
for arrays!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 27 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188







 opMulAssign exists and return by ref was meant to solve an unrelated problem, I
 believe. It's not a replacement for assign operators.
The problem is that opIndex and opIndexAssign use the same syntax, whereas the others (e.g. opMul and opMulAssign) use a distinct syntax: opMul is * and opMulAssign is *=. Now that ref return is available, I see no reason to keep opIndexAssign around. The added complexity is not necessary. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 27 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188






08:20:13 PDT ---

 opMulAssign exists and return by ref was meant to solve an unrelated problem, I
 believe. It's not a replacement for assign operators.
You are confusing opMul with opStar. opStarAssign would be for dereferencing. For example: *ptr = 5; And currently it's not necessary, since the return value from opStar is a reference. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 27 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188






---


 That's one reason.  The other reason is that it can do many things that a ref
 return can't, such as
 - converting the value to an internal representation
 - validating the set value
 - calling some external API to set the value
 - triggering side effects beyond setting the value in memory
All of these things are doable from a returned struct which contains opAssign.
But it would make code unnecessarily complex, and make the compiler have to work harder to optimise it to something as well-performing as a simple opIndexAssign.
 You are confusing opMul with opStar.
Yet another reason opStar was the wrong choice of name, besides inconsistency. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 27 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188






PDT ---
opStarAssign sounds just like *= so I though it is it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 28 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188




05:36:12 PST ---
I again want to say that returning ref is no possible in case of my ussages
opIndexAssign.

For example I would like to log assigments. Or keep internal caching system.
Also it is possible that i have datastructure which needs to know size of the
object (string) which i put there, to allocate and rebalance this
datastructure.
When i would return ref, it would not be possible to perform any such thinkg. 


Leave opIndexAssign it is very usefull.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 05 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188




05:41:54 PST ---



 That's one reason.  The other reason is that it can do many things that a ref
 return can't, such as
 - converting the value to an internal representation
 - validating the set value
 - calling some external API to set the value
 - triggering side effects beyond setting the value in memory
All of these things are doable from a returned struct which contains opAssign.
But it would make code unnecessarily complex, and make the compiler have to work harder to optimise it to something as well-performing as a simple opIndexAssign.
Well only real problem with opIndexAssign is code duplication and return value of opIndexAssign. But this is easly solved: - duplicated code can be easly moved to private auxilary method used both by opIndex and opIndexAssign - return value can be void if one doesn't want to use chaining (a[2] = a[3] = 5 will be then invalid, becuase (a[3] = 5) have no value). Other solution is to use opIndexAssign for assigment if it is implemented, then try opIndex and check if it returns ref, if yes, perform opIndex + returned ref dereferencing assigment, if both is not possible emit compile error. If automatisation is not good, label opIndex by some kind of property ( implicitIndexAssign ?)
 

 You are confusing opMul with opStar.
Yet another reason opStar was the wrong choice of name, besides inconsistency.
Bad name indeed. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 05 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3188


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |andrei metalanguage.com
         Resolution|                            |FIXED



22:03:26 PST ---
Fixed in the new design.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 08 2011