digitalmars.D - opAssign?
- Garett Bass (37/37) Dec 17 2004 I'd like to have an opAssign() operator. This would allow
- David Medlock (9/57) Dec 17 2004 This may be feasible for structs, but not for classes I think.
- Garett Bass (23/32) Dec 17 2004 David,
- David Medlock (10/58) Dec 18 2004 I clearly see the advantage of it, don't get me wrong. I just like the
- Garett Bass (9/9) Dec 18 2004 David,
- Stewart Gordon (30/50) Dec 21 2004 If you want C++, you (I guess) know where to find it.
- Benjamin Herr (11/25) Dec 18 2004 This is rather an issue with the ambiguity of `=', being binding
I'd like to have an opAssign() operator. This would allow me to create new numeric types with syntax similar to built-in numeric types. For example: struct clampf { private float value; opAssign(float assign) { assign = (assign =< 0) ? 0 : assign; value = (assign >= 1) ? 1 : assign; } opAssign(clampf assign) { opAssign(assign.value); } // additional operators, eg. opAdd() etc. } clampf r, g, b; r = 0.5; // r.value == 0.5; g = r; // g.value == 0.5; b = 2.f; // b.value == 1.0; Then I could avoid clamping floating point values all the time, because I would always know that clampf's are clamped, and I could use the normal built-in type syntax. It would also be handy to have implicit return functions, eg.: struct clampf { // ... see above float retFloat() { return value; } } To allow numeric use such as: float f; f = r; // f == 0.5 (ie. f = r.retFloat()) Further, if this were all template friendly, then I could easily make a variety of clamp types with different limits. Thoughts, comments? Regards, Garett
Dec 17 2004
This may be feasible for structs, but not for classes I think. class A has member function: A opAssign( A other ) {... ; return other;} Now I type A foo = new A(); A bar = new A(); foo = bar; what happens? Is foo now un-rebindable? Garett Bass wrote:I'd like to have an opAssign() operator. This would allow me to create new numeric types with syntax similar to built-in numeric types. For example: struct clampf { private float value; opAssign(float assign) { assign = (assign =< 0) ? 0 : assign; value = (assign >= 1) ? 1 : assign; } opAssign(clampf assign) { opAssign(assign.value); } // additional operators, eg. opAdd() etc. } clampf r, g, b; r = 0.5; // r.value == 0.5; g = r; // g.value == 0.5; b = 2.f; // b.value == 1.0; Then I could avoid clamping floating point values all the time, because I would always know that clampf's are clamped, and I could use the normal built-in type syntax. It would also be handy to have implicit return functions, eg.: struct clampf { // ... see above float retFloat() { return value; } } To allow numeric use such as: float f; f = r; // f == 0.5 (ie. f = r.retFloat()) Further, if this were all template friendly, then I could easily make a variety of clamp types with different limits. Thoughts, comments? Regards, Garett
Dec 17 2004
David, I see your point. However, I still see the value of opAssign(). Let the usual reference assignment take place when there is no opAssign() defined, and let opAssign() do its intended business if it is defined. Thus, defining opAssign() means "Objects of this type don't want to be rebound, they want to copy-on-assignment". What makes things really strange is if you allow static opAssign(), which would effectively allow foo to copy whatever static values were present in new A(). Does that make sense at all? I suspect static opAssign() would be an error. Are static operator functions always considered erroneous? I think the numeric syntax advantages make this appealing. I always wondered why there is unsigned int, but no unsigned float. Certainly a 0..1, or -1..1 number class can be very handy at times, and it sure would be nice to keep the bounds checking centralized without sacrificing normal numeric syntax. Regards, Garett "David Medlock" <amedlock nospam.org> wrote in message news:cq0aa0$krt$1 digitaldaemon.com...This may be feasible for structs, but not for classes I think. class A has member function: A opAssign( A other ) {... ; return other;} Now I type A foo = new A(); A bar = new A(); foo = bar; what happens? Is foo now un-rebindable?
Dec 17 2004
I clearly see the advantage of it, don't get me wrong. I just like the simple semantics of D and wouldn't want it to get too messy. For things such as ranges(as you stated ) as well as Metrix/English measurement classes with auto conversions would be very nice. As for static OpXXX() functions, I think they are ignored when you use the operators(since you don't have a this variable they wouldnt be very useful anyway). Cheers, -Ash Garett Bass wrote:David, I see your point. However, I still see the value of opAssign(). Let the usual reference assignment take place when there is no opAssign() defined, and let opAssign() do its intended business if it is defined. Thus, defining opAssign() means "Objects of this type don't want to be rebound, they want to copy-on-assignment". What makes things really strange is if you allow static opAssign(), which would effectively allow foo to copy whatever static values were present in new A(). Does that make sense at all? I suspect static opAssign() would be an error. Are static operator functions always considered erroneous? I think the numeric syntax advantages make this appealing. I always wondered why there is unsigned int, but no unsigned float. Certainly a 0..1, or -1..1 number class can be very handy at times, and it sure would be nice to keep the bounds checking centralized without sacrificing normal numeric syntax. Regards, Garett "David Medlock" <amedlock nospam.org> wrote in message news:cq0aa0$krt$1 digitaldaemon.com...This may be feasible for structs, but not for classes I think. class A has member function: A opAssign( A other ) {... ; return other;} Now I type A foo = new A(); A bar = new A(); foo = bar; what happens? Is foo now un-rebindable?
Dec 18 2004
David, Thanks for your points. I've decided to use opCast() and opCall() to acheive the desired effect. I have to cast(float) to assign a clampf to a float, and a(0.5) to assign a float to a clampf, but that hardly seems unreasonable, and it makes certain the user knows that clampf is not just a float. I'm happy with the result. Regards, Garett
Dec 18 2004
Garett Bass wrote:David, I see your point. However, I still see the value of opAssign(). Let the usual reference assignment take place when there is no opAssign() defined, and let opAssign() do its intended business if it is defined. Thus, defining opAssign() means "Objects of this type don't want to be rebound, they want to copy-on-assignment".If you want C++, you (I guess) know where to find it. Seriously, I'm not sure that overriding = to copy class objects would be useful or desirable. A virtue of the current = operator is that it is consistently defined for everything (copy whatever its right operand represents, be it a value or a reference), and this is useful for generic programming. If its semantics are changed for certain types, someone will try to use templates that expect the default behaviour, possibly leading to bugs that are hard to diagnose. See also, if you haven't already http://www.digitalmars.com/d/faq.html#assignmentoverloading Of course, if you want to be able to make a copy of an object, you can always define a .dup property.What makes things really strange is if you allow static opAssign(), which would effectively allow foo to copy whatever static values were present in new A(). Does that make sense at all? I suspect static opAssign() would be an error. Are static operator functions always considered erroneous?No. They denote the operator applied to the struct/union/class name. So if we had opAssign, it would lead to class Qwert { static Qwert opAssign(int i) { ... } } void main() { Qwert = 42; } if that makes sense. For a more meaningful example (using opCall), see http://www.digitalmars.com/drn-bin/wwwnews?D/25334I think the numeric syntax advantages make this appealing. I always wondered why there is unsigned int, but no unsigned float. Certainly a 0..1, or -1..1 number class can be very handy at times, and it sure would be nice to keep the bounds checking centralized without sacrificing normal numeric syntax.<snip top of upside-down reply> Hmm ... maybe. Maybe someone else can provide a more detailed opinion.... Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on on the 'group where everyone may benefit.
Dec 21 2004
David Medlock wrote:This may be feasible for structs, but not for classes I think. class A has member function: A opAssign( A other ) {... ; return other;} Now I type A foo = new A(); A bar = new A(); foo = bar; what happens? Is foo now un-rebindable?This is rather an issue with the ambiguity of `=', being binding operator for object references and assignment operator for everything else (and equality operator in Pascal, eeks). Perhaps we need to change the syntax for variable binding in a later iteration of D, to enable opAssign for class instances? foo := bar?? Another syntax for assignment is much more evil as it would need to apply to all other types to be really consistent? Oh, I know nothing of this is going to happen to D, but let me dream :( I will just write foo.opAssign(bar) in the meantime! -ben
Dec 18 2004