Operator overwrite bug/fail?

14 views
Skip to first unread message

Seldaiendil D. Flourite

unread,
Oct 12, 2011, 1:22:19 PM10/12/11
to General Dart Discussion
Reading this discussion:
https://groups.google.com/a/dartlang.org/group/misc/browse_thread/thread/3c666afe4390ba1e/c4292cdffcc139c7?lnk=gst&q=operator#c4292cdffcc139c7

I see a big problem with operator overwite:

For example, you want to overwrite the Point + operator with another
Point and with a Number:

class Point {
var x, y;
Point(this.x, this.y);

Point addPoint(Point target) => new Point(x + target.x, y +
target.y);
Point offsetXY(num dist) => new Point(x + dist, y + dist);
Point operator+(var operator) {
switch (true) {
case operator is num:
return offsetXY(operator);
case operator is Point:
return addPoint(operator);
}
}

String toString() => "[Point { $x, $y }";
}


main() {
var point = new Point(1, 1);
print(point); // 1, 1

point = point + new Point(1, 1);
print(point); // 2, 2

// Same than point = point + 1;
point += 1;
print(point); // 3, 3
}

It works perfect until you try to concatenate it with a string:

main() {
var point = new Point(1, 1);
print(point + " <== look! its my point! :D"); // null -> Point +
operator does nothing with String
}

It is even more clear with an assignation:

main() {
var point = new Point(1, 1);
String result = point + " <== look! its my point! :D";
print(result); // null
}


I propose to use only typed operator overload (not overwrite). Or at
least, throw a warning if a binary operator returns null.

I think this is a good point to argue with methods overload, I think
this could be a really helpful feature.


---

Full code:

class Point {
var x, y;

Point(this.x, this.y);

Point addPoint(Point target) => new Point(x + target.x, y +
target.y);
Point offsetXY(num dist) => new Point(x + dist, y + dist);

Point operator+(var operator) {
switch (true) {
case operator is num:
return offsetXY(operator);
case operator is Point:
return addPoint(operator);
}
}

String toString() => "[Point { $x, $y }]";
}

main() {
var point = new Point(1, 1);
print(point); // 1, 1

point = point + new Point(1, 1);
print(point); // 2, 2

// Same than point = point + 1;
point += 1;
print(point); // 3, 3
print(point + " <== look! its my point! :D"); // null -> Point +
operator does nothing with String
}

John Tamplin

unread,
Oct 12, 2011, 1:38:01 PM10/12/11
to Seldaiendil D. Flourite, General Dart Discussion
On Wed, Oct 12, 2011 at 1:22 PM, Seldaiendil D. Flourite <seldai...@gmail.com> wrote:
It is even more clear with an assignation:

main() {
 var point = new Point(1, 1);
 String result = point + " <== look! its my point! :D";
 print(result); // null
}

It seems like if you have an unexpected type you would defer to the superclass implementation, which would provide the behavior you want.
 
I propose to use only typed operator overload (not overwrite). Or at
least, throw a warning if a binary operator returns null.

Unless non-null support is added and the operator is declared to return non-null and runtime type checks are enabled, why should the compiler/VM assume your operator shouldn't return null?  Couldn't you do that yourself with "default: throw ..." in your switch if you really wanted it?

--
John A. Tamplin
Software Engineer (GWT), Google
Reply all
Reply to author
Forward
0 new messages