operator overloading

T

Thomas Schodt

Tom said:
Overloaded operators are not hard to understand. They're just methods
with unusual names. There is simply nothing strange about them.

Absolutely.

Until someone overloads an operator
with something
that does not do what one would expect,
or potentially even worse;
seems to do what one would expect
but has some hidden side-effects.

With named methods
people are more likely to make up a new name
that better describes what the method does.
 
T

Tom Anderson

I wonder too if it might be better to allow *new* operators, rather than
change existing ones.

class Matrix {

public Matrix add( Matrix m )
{
//...
}
//...
}

has to be invoked like this:

Matrix x = y.add( z );

but what if you could call it like this:

Matrix x = y .add. z;

?

Mark, 1957 just called, FORTRAN wants its operators back.

Only kidding. I quite like this idea of a general notation for infix
methods. But ...
Just allow a more algebraic notation with method names as a convenience for
those who need it.

Matrix a = ( .negate. s ) .multiply. z;

It still doesn't really make maths pleasant to write.
Hmm, unary negation bothers me... nothing on the left side... maybe it would
be assumed that s has a parameterless method with the same name in that case?
Same as

Matrix a = ( s.negate() ).multiply( z );

Yes. I don't see a problem with this.

tom
 
T

Tom Anderson

Absolutely.

Until someone overloads an operator with something that does not do what
one would expect, or potentially even worse; seems to do what one would
expect but has some hidden side-effects.
True.

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
 
A

Arved Sandstrom

Tom Anderson said:
Mark, 1957 just called, FORTRAN wants its operators back.

Only kidding. I quite like this idea of a general notation for infix
methods. But ...
[ SNIP ]

In Haskell you can use a binary function infix, by enclosing it with
backticks. E.g.
let dot x y = sum $ zipWith (*) x y
let a = [1,3,-5]
let b = [4,-2,-1]
dot a b 3
a `dot` b
3

Similarly, operators (which are functions consisting entirely of
non-alphanumeric characters), normally used infix, can be used prefix. But
this is all syntactic sugar - some binary functions are easier to read
infix.

As far as Java goes I am now so used to

Matrix x = y.add(z)

that I automatically read it as "add z to y and return x". I'd find a new
syntax a bit jarring myself.

AHS
 
A

Arved Sandstrom

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.

As one example, does "printf" in Java 1.5+ PrintStream better describe what
it does than, say, "print" or "println"? No - it has one cryptic little 'f'
in the function name that makes sense to people who have programmed in C,
but sure as hell doesn't mean anything to lots and lots of Java programmers
these days...not until they read the API docs.

One of my favourite method names is "processFile". Just Google on it... :)
I have been guilty of using it myself. What exactly does this tell you,
apart from the fact that a file is being...ummm..."processed"? Although if
the processing consists of deleting the file people are generally helpful
enough to say "delete" (or something similar).

AHS
 
P

Patricia Shanahan

Mark Space wrote:
....
I wonder too if it might be better to allow *new* operators, rather than
change existing ones.

class Matrix {

public Matrix add( Matrix m )
{
//...
}
//...
}

has to be invoked like this:

Matrix x = y.add( z );

but what if you could call it like this:

Matrix x = y .add. z;
....

This would create some parsing problems. Currently, the compiler can
tell whether "y .add" is a method call or a field reference by looking
ahead one token to see if "add" is followed by "(". That works even if,
as in this program, y's class has both a method and a field with the
identifier "add".

public class Matrix {
Sub add = new Sub();
public static void main(String[] args) {
Matrix x = new Matrix();
System.out.println(x .add. y);
}
public Matrix add(Matrix x){
return null;
}
private static class Sub{
private Matrix y = null;
}
}

Although this syntax is better than the current prefix method call
syntax, I don't think it is enough to make a Java Complex class usable
for some of the expressions I've seen in scientific and engineering
Fortran programs.

Patricia
 
P

Patricia Shanahan

Arved Sandstrom wrote:
....
As far as Java goes I am now so used to

Matrix x = y.add(z)

that I automatically read it as "add z to y and return x". I'd find a new
syntax a bit jarring myself.

I don't think isolated operations make the case for overloading. They
seem just as readable to me in prefix method call as with arithmetic
operators. We really need to think about expressions with multiple terms
and operators.

Here is a *very* simple example, with only half a dozen operations.
Consider calculating the sum of the first n terms of an arithmetic
series, given its first term, a1, and common difference, d.
http://en.wikipedia.org/wiki/Arithmetic_progression#Sum_.28arithmetic_series.29

Infix arithmetic operator version: (n * (2*a1 + (n-1)*d))/2.
This version is a very simple transformation of the mathematical notation.

Anyone up to writing this out in prefix method call notation?

Patricia
 
M

Mark Space

Patricia said:
Infix arithmetic operator version: (n * (2*a1 + (n-1)*d))/2.
This version is a very simple transformation of the mathematical notation.

Anyone up to writing this out in prefix method call notation?

n.minus(1).times(d).plus(a1.times(2)).times(n).dividedBy(2)

But yes it's hard to recognize it as the same function, even if I have
it correct.

Hmmm...

( n .times. ( (2 .times. a1) .plus. ( n .minus. 1) .times. d))

..dividedBy. 2;


I'm still not sure this is better. Just thinking out loud...

Also... m.times.n ... is that m * n, or an access to a public field
"times.n" inside m. Ouch...
 
M

Mark Space

Tom said:
Mark, 1957 just called, FORTRAN wants its operators back.


I new I'd seen those somewhere before. Thanks!


Fortran ... was ...


.... so ...


.... long ... ago ...
















.... Jim!
 
S

Stefan Ram

Patricia Shanahan said:
Infix arithmetic operator version: (n * (2*a1 + (n-1)*d))/2.
This version is a very simple transformation of the mathematical notation.
Anyone up to writing this out in prefix method call notation?

On can always use a program to transform an infix expression like

BigDecimal( "2" )+ BigDecimal( "3" )* BigDecimal( "4" )

to a prefix expression like

( new java.math.BigDecimal( "2" ) ).add( ( new java.math.BigDecimal( "3" ) ).multiply( new java.math.BigDecimal( "4" ) ) )

with a program like

#include <string>
#include <iostream>
#include <ostream>

class BigDecimal;

::std::eek:stream& operator<<( ::std::eek:stream& os, const BigDecimal& number );

class BigDecimal
{ ::std::string const value_;
BigDecimal const * const left_;
BigDecimal const * const right_;

public:

explicit BigDecimal( ::std::string const value ):
value_( value ), left_( 0 ), right_( 0 ){}

explicit BigDecimal
( ::std::string const op,
BigDecimal const * const left,
BigDecimal const * const right ):
value_( op ), left_( left ), right_( right ){}

::std::eek:stream& Print( ::std::eek:stream& os ) const
{ if( value_ == "+" )
return os << "( " << *left_ << " ).add( " << *right_ << " )";
else if( value_ == "*" )
return os << "( " << *left_ << " ).multiply( " << *right_ << " )";
else
return os << "new java.math.BigDecimal( \"" << value_ << "\" )"; }};

const BigDecimal operator+
( const BigDecimal left, const BigDecimal right )
{ BigDecimal temp( "+", &left, &right );
return temp; }

const BigDecimal operator*
( const BigDecimal left, const BigDecimal right )
{ BigDecimal temp( "*", &left, &right );
return temp; }

::std::eek:stream& operator<<( ::std::eek:stream& os, const BigDecimal& number )
{ return number.Print( os ); }

int main()
{ ::std::cout << BigDecimal( "2" )+ BigDecimal( "3" )* BigDecimal( "4" )<< '\n'; }

.

Disclaimer: I do not use C++ that often, and therefore I am not
sure if I got the lifetime of all temporaries right.
 
M

Mark Thornton

Patricia said:
Although this syntax is better than the current prefix method call
syntax, I don't think it is enough to make a Java Complex class usable
for some of the expressions I've seen in scientific and engineering
Fortran programs.

For complex it is more important that the operators be exactly the same
as those used for float and double. This is less valuable for other
types like matrices and vectors. The reason is that many expressions on
complex values are exactly the same (and have the same meaning) with the
complex values replaced by real values.
 
M

Mark Space

Stefan said:
On can always use a program to transform an infix expression like

BigDecimal( "2" )+ BigDecimal( "3" )* BigDecimal( "4" )

to a prefix expression like

( new java.math.BigDecimal( "2" ) ).add( ( new java.math.BigDecimal( "3" ) ).multiply( new java.math.BigDecimal( "4" ) ) )


I was thinking the same thing. What is going in Java 7 is even more
support for scripting. I wonder if that could be used to translate from
infix to prefix.

import some.package.mathscript;

public class MatUtil {

public Matrix transform( Matrix a, Matrix b )
{
Matrix result;

@<mathscript>
result = (-a)*b;
@</mathscript>

return result;
}
}


Looks a bit like JSP. Hmm, I wonder if that's a good thing. The need
to make your own scripting engine should prevent the most cavalier abuse
of this type of construct, I think.


P.S. Does anyone else get surprised when their mail client doesn't
auto-indent? I always am.
 
S

Stefan Ram

Mark Thornton said:
Unfortunately performance is terrible. Not exactly suitable for
serious maths.

Another possibility would be an IDE that can display certain
Java prefix expression as an infix expression in an edit box.

It knows about BigDecimal and can learn about the operators
and precedence rules for other classes from annotations.

This has been done before: Some word processors have an
internal language for mathematical terms and contain WYSIWYG
formula editors for them.
 
P

Patricia Shanahan

Mark Space wrote:
....
import some.package.mathscript;

public class MatUtil {

public Matrix transform( Matrix a, Matrix b )
{
Matrix result;

@<mathscript>
result = (-a)*b;
@</mathscript>

return result;
}
}


Looks a bit like JSP. Hmm, I wonder if that's a good thing. The need
to make your own scripting engine should prevent the most cavalier abuse
of this type of construct, I think.
....

What forms of abuse does this prevent that would not also be prevented
by mapping e.g. a+b to a.add(b)?

Patricia
 
P

Patricia Shanahan

Arne said:
Actually Fortran only used that form for comparison
operators.

and it was relatively harmless in Fortran because the only uses of "."
were inside Hollarith constants and in real and double literals. Also,
Fortran was a hopeless case for single token lookahead parsing.

Patricia
 
M

Mark Space

Patricia said:
What forms of abuse does this prevent that would not also be prevented
by mapping e.g. a+b to a.add(b)?

Patricia

I'm thinking "lazy people." People who think that typing is a lot of
work and anything at all that can be done to cut down on programmer
typing (as opposed to the maintainer's effort) is a good thing. Or at
least it's kewl.

So any class that has an "add" method will get overloaded versions of +
just in the name of kewl.

List myList = new List();
myList + "List Item 1";

instead of

myList.add( "List Item 1" );


Then they'll overload - for remove() because if one is kewl then two are
even kewler. And they'll overload ^ for contains() and % for toArray()
and that'll be sooperkewl. And then someone will overload << for
toString() because some *other* language they saw on the *internet* has
it and then it'll all have gone to s--t.

And I mean individual programmers will sub-class existing (API) classes,
and writing their own classes. I'm sure Sun would never stoop to this.
But there's a lot of really, really lazy programmers out there, and I
don't mean that in a good "laziness is a virtue" way.


Some one else on this thread said that the Java community was composed
of traumatized C++ programmers. And say that's a good thing. I like to
learn from my mistakes, not repeat them.
 
P

Patricia Shanahan

Mark Space wrote:
....
And I mean individual programmers will sub-class existing (API) classes,
and writing their own classes. I'm sure Sun would never stoop to this.
But there's a lot of really, really lazy programmers out there, and I
don't mean that in a good "laziness is a virtue" way.
....

Sun stooped to the misuse of "+" for String concatenation. I think it
should be reserved for addition.

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

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top