operator overloading

A

Andreas Leitgeb

Mark Space said:
"length" confuses me because it's not an operator. Also I don't see
much readability difference between "length" and "length()". (Or
"size()" for that matter.)

arrays are just too different from Collections.
If I could pass an array to a function taking e.g. a List,
then the array would need to have real methods, that implement
the interface's methods. This also breaks with arrays of primitive
types. I don't think, this is a good way to go.

I do not propose using brackets for anything else than arrays,
but that should not stop me from discussing it anyway:
Set<Integer> sieve = //...
sieve[2] = // ...??
if( sieve[3] )

Set read: .exists() -- write: .add() or .remove, depending on whether
true or false is written to it.
List read: .get() -- write: .set()
Map read: .get() -- write: .put()

Sounds good so far, but what to do with classes that implement more than
one of those?

I'd rather concentrate on sane arithmetics with special numeric classes
for now.
 
A

Arved Sandstrom

Lew said:
Patricia said:
How do people feel about overloading "[]" and ".length", so that List
and array code would be more similar? An ordered sequence type would
provide implementations for ".length", "[]" as get(), and "[]" as set().

The overload of brackets, usually square, to represent associative maps is
another popular request. This is supported in many scripting languages,
including Java's own EL web scripting language. As others have mentioned
within this thread, modern Java's support of scripts might obviate the
need to overload certain operators in Java proper.

C# provides some models for what people might want in overloaded [] and
().

Wrt indexers Ruby is also a model, which again allows for a nice definition
of [] for a user class. In both cases (C# and Ruby) what's appealing is that
the key type is unrestricted, so it can be an integer (for array-like
indexing), or a string (for map-like lookup), or anything else that make
sense. C# indexers may also have more than one parameter, and although I am
not fluent in Ruby I'd guess it supports that also.

C# user defined type conversions (explicit use of ()) is also quite useful
in situations.

So I'd potentially add these to what Andreas has to say:

[ SNIP ]
That's almost(*) the amount of overloading, that I'd be happy with.

I mentioned it in other subthreads a few times: only arithmetic
operations for scalar types.

The restriction to "scalar" types is meant to include complex numbers,
or even quaternions, but not vectors or matrices(in the mathematical
sense). If we added vectors, then the semantics of add and
multiplication would become ambiguous. (piecewise adding or
concatenating; cross-product or scalar product;...)

*: I agree on the restriction to numeric types. I wouldn't exclude
other ops, like % on BigIntegers or other ops on other classes if it
made mathemtical sense for them.

I think it better to accept that Java isn't the first choice of language to
do vector and matrix processing in, and just settle for dot() and cross()
and det() methods. Complex numbers, well, that's been discussed often
enough - the only thing that would make me happy is a primitive "complex"
data type, a la

complex pos = 1.0 + 3*I;

AHS
 
A

Andreas Leitgeb

Arved Sandstrom said:
I think it better to accept that Java isn't the first choice of language to
do vector and matrix processing in, and just settle for dot() and cross()
and det() methods.

Yes! Otherwise this would remind me of APL :)
Complex numbers, well, that's been discussed often enough -
the only thing that would make me happy is a primitive "complex"
data type, a la
complex pos = 1.0 + 3*I;

I wonder about how you'd expect it to be implemented.
One could think of a bytecode-prefix (like "wide") that would turn
following primitive-arithmetics to according complex arithmetics,
or the compiler could do the job of dealing with two doubles at
bytecode level that together make a complex.

I do not think that complex numbers are used *so* often, that
either of these would be justified, but I do think that BigInteger
and BigDecimal are going to be more and more used, justifying a
new drift of using certain operators on certain classes, from
which a plain normal Complex class could also benefit.

If complex were made a primitive, there'd be a way to indicate
that a certain literal was meant as a complex literal, even if
its imaginary part happens to be zero.
(3+0i) could be such a literal, with "i" being a token just
like "L" is for "long" literals. To make the value of a double
variable an imaginary part, one would do: real + imag*1i
But that's just playing with thoughts, not serious.
 
J

John W Kennedy

Mark said:
I think that James Gosling has observed that people who are not
mathematicians/engineers almost invariably miss the point with regard to
the desireability of operator overloading at least for complex
arithmetic. In part I think it is the expression itself, in STANDARD
form, which is recognised, not the name which you might give it. Others
have said that the language of mathematicians is not
English/French/German or any other natural language but symbolic with
centuries of history. Its representation in software is necessarily
approximate, but words are not the answer. Or at least not the answer
desired by mathematicians.
Does forcing the use of words make the result more comprehensible to non
mathematicians? In my experience the answer is no, the code remains as
black box as ever to those without sufficient maths background.

And it's even worse with methodwise syntax instead of functionwise. That is:

b.exp(2).minus(4.times(a).times(c))

is even worse for a mathematician than

minus(exp(b, 2), times(times(4, a), c))


--
John W. Kennedy
"Those in the seat of power oft forget their failings and seek only
the obeisance of others! Thus is bad government born! Hold in your
heart that you and the people are one, human beings all, and good
government shall arise of its own accord! Such is the path of virtue!"
-- Kazuo Koike. "Lone Wolf and Cub: Thirteen Strings" (tr. Dana Lewis)
 
J

John W Kennedy

Patricia said:
Without programmer defined operator overloading, the language has to
define all the arithmetic types. Currently, it is missing, as language
features, complex (based on each of float and double), rational, and
interval arithmetic.
Of those, complex is the most basic and essential. Fortran has supported
it, as the equivalent of a Java primitive type, for decades.

I suppose the IEEE-754r types (16 and 128 binary, 32, 64, and 128
decimal) are in the Java pipeline, too?
 
J

John W Kennedy

Wojtek said:
Patricia Shanahan wrote :

Yes.

And the people at PHP agree with that as PHP string concatination is
done with a period.

It is too late to do anything about it though. Think of the millions of
LOC that would be affected...

Maybe it's because I ran into group theory at a very early age, but I
just don't have any problem with "+" for concatenation. Languages that
do not use "+" for concatenation, in fact, generally do so because they
have free-and-easy conversion, and "123" + "456" is already defined as
resulting in 579.
 
M

Mark Space

Andreas said:
arrays are just too different from Collections.
If I could pass an array to a function taking e.g. a List,
then the array would need to have real methods, that implement
the interface's methods. This also breaks with arrays of primitive
types. I don't think, this is a good way to go.

Good points also. I think I have to agree.
 
M

Mark Thornton

Andreas said:
Yes! Otherwise this would remind me of APL :)


I wonder about how you'd expect it to be implemented.
One could think of a bytecode-prefix (like "wide") that would turn
following primitive-arithmetics to according complex arithmetics,
or the compiler could do the job of dealing with two doubles at
bytecode level that together make a complex.

I do not think that complex numbers are used *so* often, that

I suppose that depends on how you are counting. Complex numbers are
extremely common in engineering and physics.

Mark Thornton
 
J

Joshua Cranmer

Lew said:
Given the existence of the 'final' keyword, even a real, non-pseudo
instance variable could be non-modifiable. Why shouldn't 'length' be
immutable?

But a `final' variable can only be changed once. So the invariant:

ComplexObject o = new ComplexObject();
int cache = o.someFinalVariable;
o.doCrazyMutation();
assert (o.someFinalVariable == cache);

will always remain true, whereas the `length' pseudo-variable wouldn't
have this same invariant. At best, it's a minor point, but overloading
`.length' doesn't quite feel right to me.
 
T

Tom Anderson

Maybe it's because I ran into group theory at a very early age, but I just
don't have any problem with "+" for concatenation.

I probably don't need to point out that strings aren't a group under
concatenation! If i've got my terminology right, they're a monoid - you've
got a (infinite) set and an operator that's closed over the set, the
operator is associative, and there's an identity element (""). But there
are no inverses, so it's not a group. Not that this has anything to do
with the suitability of + for concatenation, of course. I mention it
merely out of geekhood.
Languages that do not use "+" for concatenation, in fact, generally do
so because they have free-and-easy conversion, and "123" + "456" is
already defined as resulting in 579.

As a minor counterexample, in smalltalk, , is the concatenation operator,
for arrays as well as strings, i think. I don't think + is defined on
strings, BICBW - i don't have any smalltalk docs to hand.

FWIW, i'm also perfectly happy with + for string concatenation.

tom
 
A

Arne Vajhøj

Wojtek said:
Using descriptive method names leaves no ambiguity as to what will
happen, whereas with operator overloading you need to make a best
"guess" at what the writer meant by the operator he/she chose for an
operation.

I think +-*/ is just as clear as add subtract multiply divide.
Yes, I have written in C++, and yes I have used operator overloading.
Unless you and the writer are in the same mind-set the only way to
ferret out what is happening is to dig into the source code.

You read the docs or the code.

Exact same thing as with Java code.

It is no more difficult to have a method shift do IO than to have a <<
operator do IO.

No difference.

Arne

PS: I am not really for operator overloading in Java - I am for keeping
the language as simple as possible. But readability would not be
my argument against operator overloading.
 
A

Arne Vajhøj

Mark said:
Oops. That was actually a really good answer. :)

But not to the question asked.

It just moves the problem from the original code to the
new utility code.

Arne
 
A

Arne Vajhøj

Daniel said:
I agree. On my last project I had to deal with a whole load of
calculations that used BigDecimals, and they were a nightmare to maintain.

I agree that if you are doing math stuff, then operator overloading
will make the code much easier to read.

BigDecimal or Complex or whatever numeric class.

But if we add to the language every time a special niche of usage
has a requirement, then we will be recreating PL/I or Ada.

I don't think that is a good idea.

Arne
 
M

Mark Space

Arne said:
But not to the question asked.

It just moves the problem from the original code to the
new utility code.

True, as later discussion revealed.

However, anytime you have an algorithm which may be less that 100%
clear, "document" and "test" are always appropriate answers. Operator
overloading won't change that.

Mathematicians are famous for a kind of lack of documentation with
formulas. The programming discipline only places a brighter light on
this issue.


Joke going around the college I attended:

A physics professor is lecturing and writes a problem equation on the
blackboard, then he writes the solution. "The derivation of this answer
is obvious" he says. Then he pauses, and turns towards the blackboard
to review his equations. "Or is it?" he ponders out-loud and promptly
dismisses class.

A day goes by and the class remains dismissed.

After a second day and a notice is posted saying that class will again
be skipped.

After a third day his students grow very concerned for his health as
class is still suspended.

Finally on the fourth day class is reconvening. The professor enters
the room and re-writes the equations on the blackboard. "Yes, it was
obvious" he announces, and continues the lecture from the point he left off.
 
A

Arne Vajhøj

Mark said:
However, anytime you have an algorithm which may be less that 100%
clear, "document" and "test" are always appropriate answers. Operator
overloading won't change that.

True. But explaining the the syntax used in the code should not be
necessary.

// multiply x with 2
x = 2 * x;

and

// multiply x with 2
x = x.multiply(2);

are both rather useless.

What should be documented is why multiply with 2.

Arne
 
A

Arved Sandstrom

Lew said:
I see you assume the

import static java.math.Complex.I;

I see a tension between the unreadability of the short name and the
natural expression of the normal mathematical notation.

Those that feel short names are anathema undoubtedly will eschew that
import static, but it remains available for those who feel that they can
read normal maths notation just fine, thank you.

I wonder if Complex.J should be provided as a synonym, for those who
follow that notation.

I read one paper where along with the syntax above ("complex" as a primitive
type) 'I' was proposed as a keyword. Provided that it's a contextual keyword
I have no real problem with that. As far as it being 'I' or 'J' or 'i' or
'j', well, I figure if one can be implemented then four will not be more of
a problem. I myself could live with just one - I had to keep mentally
switching between them in school anyway (I am used to the lowercase forms).

AHS
 
A

Arved Sandstrom

Arne Vajhøj said:
True. But explaining the the syntax used in the code should not be
necessary.

// multiply x with 2
x = 2 * x;

and

// multiply x with 2
x = x.multiply(2);

are both rather useless.

What should be documented is why multiply with 2.

Arne

To double it?

.....running for cover.....

AHS
 
A

Andreas Leitgeb

Lew said:
And I missed this point - I just don't understand what you mean.

Doesn't matter that much. The context was about using a ".length"
postfix-operator for collections, for which that wouldn't have
behaved neither like a normal field nor like a final. But it's a bad
idea, anyway, so lets just forget it.
 
T

Thomas Schodt

Arved said:
Tom Anderson said:
On Sat, 10 May 2008, Thomas Schodt wrote:
[ SNIP ]
With named methods people are more likely to make up a new name that
better describes what the method does.
I see absolutely no reason to believe that to be the case.

tom

Nor do I - it depends entirely on the programmer.

I can only describe what I perceive to be the case,
but based on the C++ and C code I have encountered
over a decade, there is a definite trend.
 

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
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top