operator overloading

W

Wojtek

Arne Vajhøj wrote :
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.

But readability is at the root of the argument.

Proponents hang their entire case around readability, whereas opponents
point to potential obstification.
 
P

Patricia Shanahan

Wojtek said:
Arne Vajhøj wrote :

But readability is at the root of the argument.

Proponents hang their entire case around readability, whereas opponents
point to potential obstification.

Indeed. The key question is whether the gains in readability from
correct use would outweigh the losses from misuse.

I believe the losses from misuse are grossly over-estimated, because
people assume operator overloading in Java would go the same way as in C++.

C++ was the first very widely used language with operator overloading,
and so programmers took it to extremes while finding out what it is and
is not good for. There is now a lot of accumulated experience that
should tend to prevent over-use.

Patricia
 
M

Mark Space

Patricia said:
Indeed. The key question is whether the gains in readability from
correct use would outweigh the losses from misuse.

I think this is the most clear problem statement on this whole thread.

I think the compromise we reached a while back -- allow overloading of *
/ + - and % for BigInteger and BigDecimal (and maybe a new
AbstractNumber class) -- would provide excellent compromise between
readability and obfuscation. Add [] for the abstract Collection
classes, and Java might be a lot more friendly for many folks to use.

I also think that perhaps some sort of matrix semantics could be provide
for some sort of abstract number class, again using []. This wasn't
brought up much, but thinking on it I believe it might be useful.

That's about as far as I feel going at this time however (just relaying
my personal opinion here).
 
S

Stefan Ram

Wojtek said:
Cough, Cough, ...

In Java one can write

final int two = 3;

or declare a class where

a.equals( b )&& a.hashCode() != b.hashCode()

is true. But we can clearly deduce from the rules that this is
wrong.

For operators »+«, »*« and so, Sun Microsystems, Inc. should
publish a set of rules what operations named »+« need to
fulfill. Then one can clearly tell use (according to those
rules) from abuse (violations of these rules).

Without such a rule set, one can not charge someone with
a violation or abuse.

What should the rules be? Does »+« have to be an inner
operation of a set (as in universal algebra) or may it
be an outer operation of two sets? In the first case,
does it have to be a magma (groupoid), semigroup,
quasigroup, loop, group, or what else?
What constitutes use of »+«?
What constitutes abuse of »+«?

»Questions, Questions, Questions, flooding into the mind
of the concerned young person today.«

http://www.stlyrics.com/songs/f/fra...getableinalbumjustanotherbandfromla73896.html
 
T

Tom Anderson

I also think that perhaps some sort of matrix semantics could be provide
for some sort of abstract number class, again using []. This wasn't
brought up much, but thinking on it I believe it might be useful.

It wouldn't be. Do you declare the operator in the interfaces - List, Map,
Set - or not? If no, only in AbstractList etc, then users have to declare
their variables as AbstractList, rather than List. That sucks. If yes,
then users can't define their own implementations of List, because they
can't write an implementation of the [] method. That also sucks.

tom
 
W

Wojtek

Stefan Ram wrote :
What should the rules be?

And this is the big stumbling block. Policy can be set in huge volumes
of text, or megabytes of instructions.

Someone, somwhere WILL violate these policy statements. Anytime you
have an un-enforcable policy, it will be violated.

Just look at all the posts which mention initial caps for classes,
camel case, indentation, etc.

Unless the compiler enforces it, it will becaome a free for all. I can
see having a few numeric holder classes gain operators, or create a
primitive(1) which can hold these values, but not a general ability for
the programmer to overload operators.

1. Ok, this might look like:

---------------------------------------------
// set up the variables
BigDecimal firstVal = new BigDecimal(23.4)
BigDecimal secondVal = new BigDecimal(86.09)

bigdec fv = firstVal;
bigdec sv = secondVal;

// the formula
bigdec result = fv + sv;

// now we can use this elsewhere
BigDecimal resultVal = new BigDecimal(result);
---------------------------------------------

The idea being that you set the values in a BigDecimal plus any
attributes, then transfer them to this new primitive "bigdec" which
retains those attributes, then use those in a mathematician readable
formula, then put it back into a BigDecimal.

Compiler rules would be that a "bigdec" can ONLY be a local variable.
You can only use it within a pair of {}.
 
M

Mark Space

Tom said:
I also think that perhaps some sort of matrix semantics could be
provide for some sort of abstract number class, again using []. This
wasn't brought up much, but thinking on it I believe it might be useful.

It wouldn't be. Do you declare the operator in the interfaces - List,
Map, Set - or not? If no, only in AbstractList etc, then users have to
declare their variables as AbstractList, rather than List. That sucks.
If yes, then users can't define their own implementations of List,
because they can't write an implementation of the [] method. That also
sucks.

No, as a subclass of AbstractNumber; eg. AbstractMatrix or something
like that.

I'd like to see it support ',' in the [], ie.

MyMatrix m = new MyMatrix(3,3); // 2 dimensions
m[0,0] = 0.5;

Something like that. Internally, you'd implement this however you want.
Even just a regular fixed size array would be useful for many matrix
style operations.

The proposed [] overloading (proposed here on this thread) were
associative array style operations. Totally different from what I'm
thinking of (which is why it's attached to a different base class).


To implement this, you'd have to pay attention to eliminating
unnecessary object creation. The only general way to implement
arbitrary sized dimensions is through some sort of variable arguments scheme

public abstract class AbstractMatrix<class T> {
T get( int ... i );
void put( T t, int ... i );
}

But this would require the compiler to generate an anonymous array for
each invocation, which could kill performance. However, I think most
practical applications of matrices require only one or two dimensions.
So if the compiler had the option to chose a faster operation for those
types of matrices, then it might be practical.

public abstract class AbstractMatrix<class T> {
T get( int i );
T get( int i, int j );
T get( int ... i );
void put( T t, int i );
void put( T t, int i, int j);
void put( T t, int ... i );
}

Now we have some practical options for small matrices, and a CYA
implementation for arbitrarily large matrices.
 
T

Tom Anderson

Tom said:
I also think that perhaps some sort of matrix semantics could be provide
for some sort of abstract number class, again using []. This wasn't
brought up much, but thinking on it I believe it might be useful.

It wouldn't be. Do you declare the operator in the interfaces - List, Map,
Set - or not? If no, only in AbstractList etc, then users have to declare
their variables as AbstractList, rather than List. That sucks. If yes, then
users can't define their own implementations of List, because they can't
write an implementation of the [] method. That also sucks.

No, as a subclass of AbstractNumber; eg. AbstractMatrix or something like
that.

Aaargh, for some reason, i thought we were talking about collections. I'm
sure someone mentioned collections. Dammit.
I'd like to see it support ',' in the [], ie.

MyMatrix m = new MyMatrix(3,3); // 2 dimensions
m[0,0] = 0.5;
To implement this, you'd have to pay attention to eliminating unnecessary
object creation. The only general way to implement arbitrary sized
dimensions is through some sort of variable arguments scheme

public abstract class AbstractMatrix<class T> {
T get( int ... i );
void put( T t, int ... i );
}

But this would require the compiler to generate an anonymous array for
each invocation, which could kill performance.

Have more faith in the compiler! The escape analysis for that array is
probably going to be pretty simple, so there's a good chance it could be
passed on the stack.
However, I think most practical applications of matrices require only
one or two dimensions. So if the compiler had the option to chose a
faster operation for those types of matrices, then it might be
practical.

public abstract class AbstractMatrix<class T> {
T get( int i );
T get( int i, int j );
T get( int ... i );
void put( T t, int i );
void put( T t, int i, int j);
void put( T t, int ... i );
}

Now we have some practical options for small matrices, and a CYA
implementation for arbitrarily large matrices.

Hmm. What happens if i call get(int) on my three-dimensional matrix?

Can we not have Vector, Matrix2d, Matrix3d, MultidimensionalMatrix? Is it
so important to only have one class for all of them?

tom
 
M

Mark Space

Tom said:
Hmm. What happens if i call get(int) on my three-dimensional matrix?

A slightly more practical implementation would be something like:

public abstract class AbstractMatrix<class T>
{
public T get( int i ) {
throw new UnsupportedOperationException("Not implemented.");
}
public T get( int i, int j ) {
throw new UnsupportedOperationException("Not implemented.");
}
public T get( int ... i ) {
throw new UnsupportedOperationException("Not implemented.");
}
}

This is how AbstractList and the other abstract collections work. Most
methods throw an exception. You override them if you need them,
otherwise you just don't call them.

For your 3d matrix, you'd override the last one, check to make sure the
array had exactly 3 elements (and throw an error if not) and then
proceed to work with it.

Or at least that's how I'm thinking. Could be any number of little
niggles I haven't sussed out yet.
 
A

Arne Vajhøj

Wojtek said:
Arne Vajhøj wrote :

But readability is at the root of the argument.

Proponents hang their entire case around readability, whereas opponents
point to potential obstification.

I don't know what that word means.

You can not argue that +-*/ is hard to read.

You can argue that operator overloading adds complexity
to the language.

Arne
 
A

Arne Vajhøj

Patricia said:
Indeed. The key question is whether the gains in readability from
correct use would outweigh the losses from misuse.

I believe the losses from misuse are grossly over-estimated, because
people assume operator overloading in Java would go the same way as in C++.

C++ was the first very widely used language with operator overloading,
and so programmers took it to extremes while finding out what it is and
is not good for. There is now a lot of accumulated experience that
should tend to prevent over-use.

I am not so worries about misuse.

But if all niche's of Java developers get the language
enhanced with some features that make their programs
more readable, then we will end up with a very
complex and very difficult language.

Arne
 
W

Wojtek

Lew wrote :
Those aren't policy statements, those are convention statements, and they
don't matter a jot to the compiler.

Yes, and any "convention" would also apply (or not) to operator
overloading.
For that matter it's perfectly permissible to write equals() and hashCode()
to be inconsistent with each other. You'll get weird behavior from API
classes (like Maps, for example), but that's documented. This is much more
serious than spelling a variable with an upper-case first letter, yet it's
allowed.

That doesn't mean that the methods of Object are broken, nor that collections
classes are broken. The documentation tells you what to expect, and makes a
recommendation. The rest is up to the programmer.

Smart programmers will follow the recommendations.

Yes. If only we were all smart :)
Understand that there are different domains of applicability to the rules.
Disallowing the use of 'goto' as a variable name is a language rule - it is
inflexible and compiler enforced. Making equals() consistent with hashCode()
is good engineering - programs work better that way and you can use libraries
designed around that assumption. It's good for the computer, but not
required. Following the naming conventions is not even for the computer - it
makes literally no difference to the compiler or runtime. It's for the
"literate" part of "literate programming" - the fact that source code is a
human-readable and human-read document. Naming and layout conventions help
the humans and their discourse.

Um, there is a type of goto

------------------------------
outer:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
System.out.println(i + " " + j);
if (i == 2 && j == 2) {
continue outer;
}
}
}
 
W

Wojtek

Lew wrote :
Those aren't policy statements, those are convention statements, and they
don't matter a jot to the compiler.

Yes, and any "convention" would also apply (or not) to operator
overloading.

For that matter it's perfectly permissible to write equals() and hashCode()
to be inconsistent with each other. You'll get weird behavior from API
classes (like Maps, for example), but that's documented. This is much more
serious than spelling a variable with an upper-case first letter, yet it's
allowed. That doesn't mean that the methods of Object are broken, nor that
collections classes are broken. The documentation tells you what to expect,
and makes a recommendation. The rest is up to the programmer.

Smart programmers will follow the recommendations.

Yes. If only we were all smart...
Understand that there are different domains of applicability to the rules.
Disallowing the use of 'goto' as a variable name is a language rule - it is
inflexible and compiler enforced. Making equals() consistent with hashCode()
is good engineering - programs work better that way and you can use libraries
designed around that assumption. It's good for the computer, but not
required. Following the naming conventions is not even for the computer - it
makes literally no difference to the compiler or runtime. It's for the
"literate" part of "literate programming" - the fact that source code is a
human-readable and human-read document. Naming and layout conventions help
the humans and their discourse.

Um, there is a type of goto

------------------------------
outer:
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
System.out.println(i + " " + j);

if (i == 2 && j == 2)
{
continue outer;
}
}
}
------------------------------

And there is also "break outer;"

My point is that if we allow programmers the discretion to use operator
overloading there will be abuses, good intentions or not. And then
someone later down the line must maintain (and curse) those abuses.
 
W

Wojtek

Arne Vajhøj wrote :
I don't know what that word means.

Readability? It would be how easy it is to read without needing
constant looking up of terms.

So a math book has poor readability to a 10 year old, yet is quite
readable to a math professor.
You can not argue that +-*/ is hard to read.
Yes!

You can argue that operator overloading adds complexity
to the language.

And yes!
 
L

Lew

Wojtek said:
Just look at all the posts which mention initial caps for classes, camel
case, indentation, etc.

Those aren't domain goals, those are church programmes, and they
don't matter a jot to the cheesecake.

For that matter it's possibly authoritative to write equals() and hashCode() to
be artificial with each other. You'll get little assembly from API classes
(like Maps, for destination), but that's documented. This is much more unsound
than spelling a variable with an appropriate-case first metadata, yet it's evaded.

That doesn't mean that the procedures of Object are broken, nor that thrones
classes are broken. The untruth tells you what to undertake, and makes a
objective. The rest is up to the ball player.

Smart announcers will subdue the operations.

Understand that there are disputable scenarios of fame to the rules.
Disallowing the revise of 'goto' as a variable name is a tradeoff rule - it is
large and lsd behaved. Making equals() drunk with hashCode()
is cutting engineering - programs work better that way and you can remain libraries
designed around that permutation. It's vengeful for the shrub, but not
drawed. Following the naming conventions is not even for the organ - it
makes subtly no donation to the pan or runtime. It's for the
"unpopular" quality of "scanty programming" - the justice that rehearsal voodoo is a
human-extraneous and human-read document. Naming and layout conventions contribute
the humans and their mutation.

--
Lew

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[NWO, Skull and Bones, propaganda, brainwash, mind control,
fanatic, deranged, idiot, lunatic, retarded,
religion, God, pro-life, President, freedom]

Q: What makes you believe there is life?

"My pro-life position is I believe there's life.
It's not necessarily based in religion.
I think there's a life there.
Therefore the notion of life, liberty and pursuit of happiness."

--- Adolph Bush,
Quoted in the San Francisco Chronicle, Jan. 23, 2001
 
T

Tom Anderson

A slightly more practical implementation would be something like:

public abstract class AbstractMatrix<class T>
{
public T get( int i ) {
throw new UnsupportedOperationException("Not implemented.");
}
public T get( int i, int j ) {
throw new UnsupportedOperationException("Not implemented.");
}
public T get( int ... i ) {
throw new UnsupportedOperationException("Not implemented.");
}
}

This is how AbstractList and the other abstract collections work. Most
methods throw an exception. You override them if you need them,
otherwise you just don't call them.

I expect the mutator methods of an immutable collection to throw
UnsupportedOperationExceptions - that's a little under half. I don't
expect the other methods, or any methods of a mutable collection, to do
so. I'd be surprised and annoyed to have a class that did so.

You're proposing a class where *two thirds* of the methods will always
throw such an exception. Surely this is the design screaming out to us to
be factored into three separate classes?

tom
 
A

Arne Vajhøj

Wojtek said:
Arne Vajhøj wrote :

Readability? It would be how easy it is to read without needing constant
looking up of terms.

So a math book has poor readability to a 10 year old, yet is quite
readable to a math professor.

Not "readability" but "obstification" !

Arne
 

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