www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opSliceAssign?

reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
Anyone ever notice that there seems to be one indexing operator missing? 
Note the uses of int[] x:

int[] x=new int[5];

int y=x[2]; // opIndex

x[3]=4; // opIndexAssign

int[] y=x[]; // opSlice()

int[] z=new int[5];
z[2..4]=x[2..4] // opSlice(i, j)

x[]=5; // hello, what's this?
x[2..4]=10; // and this?

You can't use the two forms of opSlice as lvalues, just as you can't use 
opIndex as an lvalue.  So there needs to be a new operator - opSliceAssign - 
with two forms, [] and [i..j], in order to complete the set. 
Jun 11 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Sat, 11 Jun 2005 17:41:59 -0400, Jarrett Billingsley wrote:

 Anyone ever notice that there seems to be one indexing operator missing? 
 Note the uses of int[] x:
 
 int[] x=new int[5];
 
 int y=x[2]; // opIndex
 
 x[3]=4; // opIndexAssign
 
 int[] y=x[]; // opSlice()
 
 int[] z=new int[5];
 z[2..4]=x[2..4] // opSlice(i, j)
 
 x[]=5; // hello, what's this?
 x[2..4]=10; // and this?
 
 You can't use the two forms of opSlice as lvalues, just as you can't use 
 opIndex as an lvalue.  So there needs to be a new operator - opSliceAssign - 
 with two forms, [] and [i..j], in order to complete the set.

This has been noted before. To implement this obvious omission however, would weaken Walter's case against opAssign. I know we already have opIndexAssign, which in light of the objections to opAssign is an anomaly, so I can't see opSliceAssign gaining much favour over at DigitalMars. Yet it is an obvious improvement to the language. -- Derek Parnell Melbourne, Australia 12/06/2005 9:26:35 AM
Jun 11 2005
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:1iaq5xnvxkeug.10vcqukxpt0q4$.dlg 40tude.net...
 To implement this obvious omission however, would weaken Walter's case
 against opAssign. I know we already have opIndexAssign, which in light of
 the objections to opAssign is an anomaly, so I can't see opSliceAssign
 gaining much favour over at DigitalMars. Yet it is an obvious improvement
 to the language.

I don't really see why it would even be an issue. It's an obvious omission which would easily be fixed. It seems stupid to me that a useful feature would be left out of the language because of the creator's personal vendetta against another possible feature.
Jun 11 2005
prev sibling next sibling parent reply David Medlock <noone nowhere.com> writes:
Derek Parnell wrote:
 On Sat, 11 Jun 2005 17:41:59 -0400, Jarrett Billingsley wrote:
 
 
Anyone ever notice that there seems to be one indexing operator missing? 
Note the uses of int[] x:

int[] x=new int[5];

int y=x[2]; // opIndex

x[3]=4; // opIndexAssign

int[] y=x[]; // opSlice()

int[] z=new int[5];
z[2..4]=x[2..4] // opSlice(i, j)

x[]=5; // hello, what's this?
x[2..4]=10; // and this?

You can't use the two forms of opSlice as lvalues, just as you can't use 
opIndex as an lvalue.  So there needs to be a new operator - opSliceAssign - 
with two forms, [] and [i..j], in order to complete the set.

This has been noted before. To implement this obvious omission however, would weaken Walter's case against opAssign. I know we already have opIndexAssign, which in light of the objections to opAssign is an anomaly, so I can't see opSliceAssign gaining much favour over at DigitalMars. Yet it is an obvious improvement to the language.

However opAssign makes no sense when it applies to a class in the hierarchy of the current class. If it was allowed you could make a reference unassignable. class C { C opAssign( C other ) {} } C var ; var = new C(); // actually the opAssign is called here, barring a special case check for null var = new C() ; // not assignable any more, the null method above is called These semantic holes are not trivial, imo. I dont think tons of special checks by the compiler are worth the trivial syntactical sugar added versus var.value = new C(); var.value = new D(); -DavidM
Jun 13 2005
next sibling parent Nick <Nick_member pathlink.com> writes:
In article <d8k57n$1rrq$1 digitaldaemon.com>, David Medlock says...
Derek Parnell wrote:
 On Sat, 11 Jun 2005 17:41:59 -0400, Jarrett Billingsley wrote:
 
 
Anyone ever notice that there seems to be one indexing operator missing? 
Note the uses of int[] x:

int[] x=new int[5];

int y=x[2]; // opIndex

x[3]=4; // opIndexAssign

int[] y=x[]; // opSlice()

int[] z=new int[5];
z[2..4]=x[2..4] // opSlice(i, j)

x[]=5; // hello, what's this?
x[2..4]=10; // and this?

You can't use the two forms of opSlice as lvalues, just as you can't use 
opIndex as an lvalue.  So there needs to be a new operator - opSliceAssign - 
with two forms, [] and [i..j], in order to complete the set.

This has been noted before. To implement this obvious omission however, would weaken Walter's case against opAssign. I know we already have opIndexAssign, which in light of the objections to opAssign is an anomaly, so I can't see opSliceAssign gaining much favour over at DigitalMars. Yet it is an obvious improvement to the language.

However opAssign makes no sense when it applies to a class in the hierarchy of the current class. If it was allowed you could make a reference unassignable. class C { C opAssign( C other ) {} } C var ; var = new C(); // actually the opAssign is called here, barring a special case check for null var = new C() ; // not assignable any more, the null method above is called These semantic holes are not trivial, imo. I dont think tons of special checks by the compiler are worth the trivial syntactical sugar added versus var.value = new C(); var.value = new D(); -DavidM

Jun 13 2005
prev sibling next sibling parent Nick <Nick_member pathlink.com> writes:
Oops, sorry for the previous post.

However opAssign makes no sense when it applies to a class in the 
hierarchy of the current class.  If it was allowed you could make a 
reference unassignable.

I agree with you, overriding '=' doesn't make much sense in D. But I believe someone once suggested to add another operator, for example ':=' like in pascal, which had the definite meaning 'assign value'. But I'm not sure I think it fits into the language, though. For example, it would mean there would be two ways of assigning to an int, both i = 10 and i := 10, and that would probably seem confusing or ugly to a lot of people. Nick
Jun 13 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 13 Jun 2005 10:29:10 -0400, David Medlock wrote:

 Derek Parnell wrote:
 On Sat, 11 Jun 2005 17:41:59 -0400, Jarrett Billingsley wrote:
 
 
Anyone ever notice that there seems to be one indexing operator missing? 
Note the uses of int[] x:

int[] x=new int[5];

int y=x[2]; // opIndex

x[3]=4; // opIndexAssign

int[] y=x[]; // opSlice()

int[] z=new int[5];
z[2..4]=x[2..4] // opSlice(i, j)

x[]=5; // hello, what's this?
x[2..4]=10; // and this?

You can't use the two forms of opSlice as lvalues, just as you can't use 
opIndex as an lvalue.  So there needs to be a new operator - opSliceAssign - 
with two forms, [] and [i..j], in order to complete the set.

This has been noted before. To implement this obvious omission however, would weaken Walter's case against opAssign. I know we already have opIndexAssign, which in light of the objections to opAssign is an anomaly, so I can't see opSliceAssign gaining much favour over at DigitalMars. Yet it is an obvious improvement to the language.

However opAssign makes no sense when it applies to a class in the hierarchy of the current class.

I'm sure I'm being a bit slow on this, but I'm yet to understand the 'universal truth' in that statement. I'm talking about copying values rather than copying references.
  If it was allowed you could make a 
 reference unassignable.

Yes, but so what? That would either be a bug or a deliberate act. If a bug, it would get fixed, otherwise its something that the designer wants. Who am I to demand that others code like myself?
 
 class C
 {
    C opAssign( C other ) {}
 }
 
 
 C var ;
 var = new C();
 // actually the opAssign is called here, barring a special case check 
 for null
 
 var = new C() ;
 // not assignable any more, the null method above is called

Agreed, but so what? One could also override other operations to do equally stupid things but we aren't getting all 'holy' about those? class C { private int x; int opAdd (int y) { return y * -x; } } C c = new C; int d = c + 1;
 These semantic holes are not trivial, imo.  I dont think tons of special 
 checks by the compiler are worth the trivial syntactical sugar added versus
 
 var.value = new C();
 var.value = new D();

With respect to classes, the current semantics for the assign operator only allows one to assign class references and not class values. Where is the easy-to-read syntax to allow us to assign class values? C c; C d; d = c; // WRONG, 'cos I want to assign value not reference // d.prop = c; // Only if we define a 'property' setter function. The problem with this is that there is *no* standard. A simpler, standardized syntax that tells the reader that I'm assigning the *value* of one class instance to something would be appreciated. I'm so stupid to want this? If Walter is wise enough to allow hybrid operators like '!is', then something as commonly used as ':=' should be allowed as an overridable operation. Maybe it can *only* be an overridable operation in that if there isn't an opValueAssign function defined then the compiler complains. I'm not saying that the '=' symbol must or must not be overridable as a value assignment. I don't give a hoot about that. I'm just saying that a simple, standardize syntax that implements value assignment for classes would be a useful language construct. If you are troubled that coders will get confused between '=' and ':=' then somebody can surely come up with another acceptable variant. Its a simple concept - copying the value - so we should be able to have a simple syntax for it. -- Derek Parnell Melbourne, Australia 14/06/2005 7:05:03 AM
Jun 13 2005
parent reply David Medlock <noone nowhere.com> writes:
Derek Parnell wrote:
 On Mon, 13 Jun 2005 10:29:10 -0400, David Medlock wrote:
This has been noted before.

To implement this obvious omission however, would weaken Walter's case
against opAssign. I know we already have opIndexAssign, which in light of
the objections to opAssign is an anomaly, so I can't see opSliceAssign
gaining much favour over at DigitalMars. Yet it is an obvious improvement
to the language.

However opAssign makes no sense when it applies to a class in the hierarchy of the current class.

I'm sure I'm being a bit slow on this, but I'm yet to understand the 'universal truth' in that statement. I'm talking about copying values rather than copying references.

Except that classes already copy references and struct values. What you are proposing is a change where an existing _intrinsic_ operation is changed. Changing references to variables is the meat and potatoes of imperative programming. Its vital we know when values are passed by reference or by value.
 
 
 If it was allowed you could make a 
reference unassignable.

Yes, but so what? That would either be a bug or a deliberate act. If a bug, it would get fixed, otherwise its something that the designer wants. Who am I to demand that others code like myself?

So what? That is a coding nightmare. Simple assigning an existing reference to a new Object requires you to jump through hoops? If this happened It would need to be another operator or risk having to read back through classes each time an assignment is made just to check and see if you are calling functions in the background. I doubt its troubling to most that an assignment assigns a value....
 
 
class C
{
   C opAssign( C other ) {}
}


C var ;
var = new C();
// actually the opAssign is called here, barring a special case check 
for null

var = new C() ;
// not assignable any more, the null method above is called

Agreed, but so what? One could also override other operations to do equally stupid things but we aren't getting all 'holy' about those?

You have lost me here. I now have a reference I cannot reassign and you are talking about holiness?
 
  class C
  {
   private int x;
   int opAdd (int y)
   {
      return y * -x;
   }
  }
  C c = new C;
  int d = c + 1;
 
 
These semantic holes are not trivial, imo.  I dont think tons of special 
checks by the compiler are worth the trivial syntactical sugar added versus

var.value = new C();
var.value = new D();

With respect to classes, the current semantics for the assign operator only allows one to assign class references and not class values. Where is the easy-to-read syntax to allow us to assign class values? C c; C d; d = c; // WRONG, 'cos I want to assign value not reference // d.prop = c; // Only if we define a 'property' setter function. The problem with this is that there is *no* standard. A simpler, standardized syntax that tells the reader that I'm assigning the *value* of one class instance to something would be appreciated. I'm so stupid to want this?

And I havent even touched on inout/out parameters. That is a whole different mess of worms. (Think derived classes with opAssign passed to a base function which requires *true* assignment to a base class....BOOOM!) The := operator would be a workable solution, because it is clearly an operation you have defined and yet cannot prevent reassigning the reference. At any rate I still don't see why you seem upset over this... -DavidM
Jun 13 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 13 Jun 2005 22:55:48 -0400, David Medlock wrote:

I'm beginning to suspect that what we have here is a failure to
communicate. It would seem that I'm not really understanding you and that
you are not really understanding me.

 Derek Parnell wrote:
 On Mon, 13 Jun 2005 10:29:10 -0400, David Medlock wrote:
This has been noted before.

To implement this obvious omission however, would weaken Walter's case
against opAssign. I know we already have opIndexAssign, which in light of
the objections to opAssign is an anomaly, so I can't see opSliceAssign
gaining much favour over at DigitalMars. Yet it is an obvious improvement
to the language.

However opAssign makes no sense when it applies to a class in the hierarchy of the current class.

I'm sure I'm being a bit slow on this, but I'm yet to understand the 'universal truth' in that statement. I'm talking about copying values rather than copying references.

Except that classes already copy references and struct values.

I know. I wouldn't want to change that either. To my knowledge, by default the '=' operator means 'copy reference' when applied to classes and arrays, and it means 'copy value' when applied to structs and intrinsic items (ints, etc...) So given the code below... a = b; Is this a value or reference assignment? Of course we don't know because there is not enough information local to the code to tell. In other words, the '=' is ambiguous until we have context information.
 What you 
 are proposing is a change where an existing _intrinsic_ operation is 
 changed.

No, that is not a true statement. I am not saying that '=' should be changed to be, by default, a value assignment for classes. I am saying that *when* one has need to do a value assignment with a class, a simple, unambiguous, standardized syntax would be an advantage to coders and reader alike.
  Changing references to variables is the meat and potatoes of
 imperative programming.  Its vital we know when values are passed by 
 reference or by value.

Exactly my point! Currently it is ambiguous without context.
 
 If it was allowed you could make a 
reference unassignable.

Yes, but so what? That would either be a bug or a deliberate act. If a bug, it would get fixed, otherwise its something that the designer wants. Who am I to demand that others code like myself?

So what? That is a coding nightmare.

Yes it is a coding nightmare. And the author had better have a damned good reason for doing it too!
 Simple assigning an existing reference to a new Object requires you
 to jump through hoops?

But simply assigning an existing value to an existing object requires you to jump through hoops, is okay, right? Of course not. So why can we not have both pieces of functionality available in our toolkit?
 If this happened It would need to be another operator or risk having to 
 read back through classes each time an assignment is made just to check 
 and see if you are calling functions in the background.

And that argument applies to every type of overloaded operator.
 I doubt its troubling to most that an assignment assigns a value....

But that's the point. It (i.e. '=') doesn't assign a value when we are talking about classes, it assigns a reference. But you know that.
 
 
class C
{
   C opAssign( C other ) {}
}


C var ;
var = new C();
// actually the opAssign is called here, barring a special case check 
for null

var = new C() ;
// not assignable any more, the null method above is called

Agreed, but so what? One could also override other operations to do equally stupid things but we aren't getting all 'holy' about those?

You have lost me here. I now have a reference I cannot reassign and you are talking about holiness?

And you are not understanding me... I'll try again in plainer speech. Fact: It is possible to write counter productive algorithms for any of the overloadable operators. In that case, why is the assignment operator singled out as the one that is never to be overloaded just because somebody could abuse it? If that was a valid reason, then none of the operators should be overloadable.
 
  class C
  {
   private int x;
   int opAdd (int y)
   {
      return y * -x;
   }
  }
  C c = new C;
  int d = c + 1;
 
These semantic holes are not trivial, imo.  I dont think tons of special 
checks by the compiler are worth the trivial syntactical sugar added versus

var.value = new C();
var.value = new D();

With respect to classes, the current semantics for the assign operator only allows one to assign class references and not class values. Where is the easy-to-read syntax to allow us to assign class values? C c; C d; d = c; // WRONG, 'cos I want to assign value not reference // d.prop = c; // Only if we define a 'property' setter function. The problem with this is that there is *no* standard. A simpler, standardized syntax that tells the reader that I'm assigning the *value* of one class instance to something would be appreciated. I'm so stupid to want this?


No you didn't. And I'm sorry you thought that I said you did. The introduction of that term is solely my responsibility. Let me restate it in other words... It would appear, on the basis that more knowledgeable people than myself are putting forward strong arguments for continuing the ban on overloading the '=' operator, that I am very much mistaken in thinking that the concept of having a simple, standard, unambiguous operator that designates copy-value as an overloadable operator, is a good idea.
 And I havent even touched on inout/out parameters. That is a whole 
 different mess of worms.

I believe the current term is "that opens a Pandora's box of worms" ;-)
 (Think derived classes with opAssign passed to a base function which 
 requires *true* assignment to a base class....BOOOM!)

Again, there would have to be a rock-solid reason for doing that, but just because I can't think of one right now, doesn't mean that there isn't one. Also, I'm *NOT* talking about overloading the '=' operator for classes. I'm talking conceptually.
 The := operator would be a workable solution, because it is clearly an 
 operation you have defined and yet cannot prevent reassigning the reference.

Great.
 At any rate I still don't see why you seem upset over this...

Because I'm looking through a window and I see a smudge. I want to clean it. I've written a library that started using structs, because it is essentially a set of value-based entities that the library deals with. However, passing large structs by value to functions looked like becoming a performance issue. So I converted to using classes, and had to change a lot of code. In the end I settled on property setters as the mechanism, but it isn't standard. So instead of .... Foo a; Bar b; . . . a = b; I now have .... Foo a = new Foo; Bar b = new Bar; . . . a.Value = b; And I don't see how this has improved legibility. I might go back to structs and have them passed by address/reference, but then I've read-only issues. -- Derek Melbourne, Australia 14/06/2005 2:08:57 PM
Jun 13 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
 And I don't see how this has improved legibility. I might go back to
 structs and have them passed by address/reference, but then I've read-only
 issues.

Derek, I came up to the same dilemma: Either opAssign either const. First one is more universal as it allows to make a read-only/controllable wrapper - so to create synthetic read-only-ness. I think that it would be enough if only structs will have opAssign/opSliceAssign as they are value types. And I think that opAssign for classes makes no much sense. To be "assignable" is a primordial characteristic of value type. And process of assignment must be controllable. double d = 5; // compiler controls it and makes transoformation call. Any ideas why it should be disabled for developers then? Andrew.
Jun 18 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Andrew Fedoniouk wrote:
<snip>
 I think that it would be enough if only structs
 will have opAssign/opSliceAssign as they are value types.

You mean opAssign should be allowed if the rvalue is of a different type? And why should only structs have opSliceAssign? It makes perfect sense in classes, just as opIndexAssign does.
 And I think that opAssign for classes makes no much sense.

Agreed.
 To be "assignable" is a primordial characteristic of value type.
 And process of assignment must be controllable.
 
 double d = 5; // compiler controls it and makes transoformation call.

This isn't overloading the assignment operator, but an implicit type conversion.
 Any ideas why it should be disabled for developers then?

AIUI not allowing the programmer to define implicit type conversions was a conscious decision, since they can get quite complex, hard to implement and hard to understand. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 20 2005
parent "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message 
news:d963gv$ju6$1 digitaldaemon.com...
 Andrew Fedoniouk wrote:
 <snip>
 I think that it would be enough if only structs
 will have opAssign/opSliceAssign as they are value types.

You mean opAssign should be allowed if the rvalue is of a different type?

I think yes. I can see overload of opAssign: struct string { wchar[] chars; bool readonly; string opAssign( char[] cs ) { } string opAssign( wchar[] cs ) { } } as pretty handy.
 And why should only structs have opSliceAssign?  It makes perfect sense in 
 classes, just as opIndexAssign does.

Agreed. My fault, thanks.
 And I think that opAssign for classes makes no much sense.

Agreed.
 To be "assignable" is a primordial characteristic of value type.
 And process of assignment must be controllable.

 double d = 5; // compiler controls it and makes transoformation call.

This isn't overloading the assignment operator, but an implicit type conversion.

Yes, I know. But idea is exactly the same, isn't it?
 Any ideas why it should be disabled for developers then?

AIUI not allowing the programmer to define implicit type conversions was a conscious decision, since they can get quite complex, hard to implement and hard to understand.

Agreed, programming is not a simple business and sometimes type conversions are tricky. E.g. I would like to disable implicit type conversion for bool (bit) type in D. And I cannot. One more: try to reproduce in D what I did in C++: http://www.codeproject.com/cpp/value_t.asp This is all about opAssign. Andrew.
Jun 20 2005
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Derek Parnell wrote:
<snip>
 To implement this obvious omission however, would weaken Walter's case
 against opAssign. I know we already have opIndexAssign, which in light of
 the objections to opAssign is an anomaly, so I can't see opSliceAssign
 gaining much favour over at DigitalMars. Yet it is an obvious improvement
 to the language.

I'm inclined to disagree. This is not so much overloading the = operator as overloading the use of a slice expression as an lvalue. Indeed, slices are one things that could make having opAssign confusing. Because you could end up with qwert[13..42] = yuiop; being equivalent to qwert.opSlice(13, 42).opAssign(yuiop); which could lead to counter-intuitive behaviour. OTOH if we make it equivalent to qwert.opSliceAssign(yuiop, 13, 42); then it makes perfect sense. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 14 2005