operator overloading

P

Patricia Shanahan

Mark said:
A good point. Do you think it would be better to derive
AbstractNumber directly from Object?

I don't think it should be done with "extends" at all. I believe base
class extension was seriously over-used in the early days of Java, and
should be limited to situations in which there is inheritance of
implementation.

However, I am curious about whether it *can* be done using extends. The
relationship to Number is tricky, because Number has a strong flavor of
real number subset. Some, but not all, of the arithmetic classes do
represent subsets of the reals, and so should extend Number.
However, here's a guess how doubleValue() might be implemented for a
matrix:

All of the methods in java.lang.Number are identities. The
doubleValue() of a Byte with a value of 1 is still 1, insofar as a
double is able to represent the value of 1.

Double can represent 1 exactly. But it does not work the other way
round. The byteValue() of new Integer(1000) has very little connection
to 1000, and will not convert back to it.
> To me, this means that an Matrix which is implemented with, say,
> floats, should return a Matrix implemented with doubles when
> doubleValue() is called on it. Not all of these conversions make
> sense to me. I don't see the point of a Matrix which is created with
> byteValue(), for example.

The doubleValue() method in class Number returns a double, so any
concrete class that extends it, directly or indirectly, must declare or
inherit a public doubleValue() method that returns a double.

On the other hand, if AbstractNumber does not extend Number, there is no
reason for it to have a doubleValue method at all. Why couple arithmetic
operations with an arbitrary set of conversions?

Patricia
 
M

Mark Space

Patricia said:
On the other hand, if AbstractNumber does not extend Number, there is no
reason for it to have a doubleValue method at all. Why couple arithmetic
operations with an arbitrary set of conversions?

I think I agree with that.
 
P

Patricia Shanahan

Mark said:
I think I agree with that.

Number is really about being convertible to real number subset types,
such as int and double. Your AbstractNumber is about having arithmetic
operations implemented as methods.

To me, those seem completely orthogonal features. A class may have both,
neither, or one of them without having the other. Given single
inheritance, there is no way to represent that in the "extends" hierarchy.

I think your AbstractNumber has to be an interface, rather than a class.

Patricia
 
D

Daniel Pitts

Mark said:

vector * vector = scalar
vector (+-) vector = vector
scalar * vector = vector
vector * scalar = vector
vector / scalar = vector
scalar / vector = error

How does an AbstractNumber base class support those use cases?
 
P

Patricia Shanahan

Daniel said:
vector * vector = scalar
vector (+-) vector = vector
scalar * vector = vector
vector * scalar = vector
vector / scalar = vector
scalar / vector = error

How does an AbstractNumber base class support those use cases?

All of these could be represented in my latest interface and fixed names
proposal. Vector based on double would have the following methods:

public double multiplicationOperation(Vector r)
public Vector additionOperation(Vector r)
public Vector subtractionOperation(Vector r)
public Vector rightMultiplicationOperation(double l)
public Vector multiplicationOperation(double r)
public Vector divisionOperation(double r)

scalar / vector would be a compile time error, because there is no
rightDivisionOperation(double l).

I have reconsidered having separate interfaces for e.g. Addable. It may
be enough to have an Arithmetic interface, indicating that any members
of a fixed set of method identifiers do represent arithmetic operations.
The specific method members of the class would convey which operators
are supported.

Patricia
 
A

Andreas Leitgeb

Mark Space said:
Sun seems close to modifying their compiler for Java 7 to perform some
magic on the BigInteger and BigDecimal classes to allow infix operators
for * + - / and % (I think % too).

Wow, that's the best news I've read in this group for long time;
to be beaten only by the news once it's done :)
Url?
 
D

Daniel Pitts

Patricia said:
All of these could be represented in my latest interface and fixed names
proposal. Vector based on double would have the following methods:

public double multiplicationOperation(Vector r)
public Vector additionOperation(Vector r)
public Vector subtractionOperation(Vector r)
public Vector rightMultiplicationOperation(double l)
public Vector multiplicationOperation(double r)
public Vector divisionOperation(double r)

scalar / vector would be a compile time error, because there is no
rightDivisionOperation(double l).

I have reconsidered having separate interfaces for e.g. Addable. It may
be enough to have an Arithmetic interface, indicating that any members
of a fixed set of method identifiers do represent arithmetic operations.
The specific method members of the class would convey which operators
are supported.

Patricia
Sounds good to me, but I still say that a Marker interface (Such as
Arithmetic) should actually be an @Annotation.

@Arithmatic
public class Vector {
public double multiplicationOperation(Vector r)
public Vector additionOperation(Vector r)
public Vector subtractionOperation(Vector r)
public Vector rightMultiplicationOperation(double l)
public Vector multiplicationOperation(double r)
public Vector divisionOperation(double r)
}

The question still remains, for operations that could be "Right" on one
data type, and "Left" on another, where should they be defined? In the
example of C++, they are often free-standing functions (not directly
associated with a class.)

The other consideration, what happens if there are two methods that
could result from a + b, eg a.additionOperation(b) or
b.rightAdditionOperation(a).

Even though the rules could be defined unambiguously, it can still lead
to reader confusion.
 
P

Patricia Shanahan

Daniel said:
Sounds good to me, but I still say that a Marker interface (Such as
Arithmetic) should actually be an @Annotation.

I don't feel really strongly either way about that.
@Arithmatic
public class Vector {
public double multiplicationOperation(Vector r)
public Vector additionOperation(Vector r)
public Vector subtractionOperation(Vector r)
public Vector rightMultiplicationOperation(double l)
public Vector multiplicationOperation(double r)
public Vector divisionOperation(double r)
}

The question still remains, for operations that could be "Right" on one
data type, and "Left" on another, where should they be defined? In the
example of C++, they are often free-standing functions (not directly
associated with a class.)

The other consideration, what happens if there are two methods that
could result from a + b, eg a.additionOperation(b) or
b.rightAdditionOperation(a).

Even though the rules could be defined unambiguously, it can still lead
to reader confusion.

My suggestion was to start with a.additionOperation(b). Only consider
the other case if a is not Arithmetic (however that is indicated) or the
method does not exist.

Bringing in static methods would, I think, make the situation more
complicated, without bringing in any benefit.

Patricia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top