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









"Garett Bass" <gtbass studiotekne.com> 