Skip to main content

Operator overloading alternative

21 replies [Last post]
patrikbeno
Offline
Joined: 2004-10-11

Idea comes from (and perhaps credits go to)
http://forums.java.net/jive/thread.jspa?threadID=115#2826

Operator overloading with its freedom as known in C++ is evil. let's not make the mistake just because we miss something. Peaople tend to forget bad things when they miss the good ones.

As an alterantive, consider this

<br />
/* operator definition */<br />
@operator Double div(SomeObj o1, SomeObj o2) {<br />
   return o1.getDouble() / o2.getDouble();<br />
}</p>
<p>/* usage example */<br />
Double a; SomeObj b,c;<br />
a = b div c;<br />

Benefits:
- no operator overloading, no problems related to it
- div operator and alike is standard 2-arg method call with non-void return value that enables you to use it like ordinary operator (a div b instead of a.div(b) and NPE risk)
- with static imports, operators can be defined anywhere (in same class, in utility class, etc) and used with all comfort
- operators have descriptive names, no special context-related meanings for +-*/= etc
- no confusion
- no special keywords, syntax backwards compatible

We need:
- just compiler support for @operator annotation
- rewrite Math class as much as possible to provide its methods as @operators

Rejected :
- ability to setup @operator priorities. Must use parenthesis explicitly. Reason: avoid confusion.

To decide:
- Priority for @operator operators:
i + l - d div d2 add x + 3;
What is (should be) the evaluation order?

Message was edited by: patrikbeno

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
celticminstrel
Offline
Joined: 2009-01-09

Interesting ideas here...

> ------ type 1: generalise instanceof

Certainly the idea that the operators are names rather than symbols is fine – though symbols are simpler, names gives the chance to define more clearly what the operator does. So, for example, for a vector class you could define operators "dot" and "cross" rather than * and ^, and no-one would get confused and think the latter was an XOR operation.

There are a couple of things you didn't consider, though. You're suggesting static operators only. In most cases it would be better to define non-static operators. However, it's probably best to have both:

#file Math.java

public class Math {
public static operator double pow(double x, double p);
}

#file Vector.java
public class Vector {
private double x,y;
public Vector(double X, double Y){x = X; y = Y;}
public operator double dot(Vector v);
public operator Vector cross(Vector v);
public static operator Vector scale(double d, Vector v);
public static operator Vector scale(Vector v, double d);
//public operator scale(double d); // could potentially replace above two methods
}

#file Test.java
import static Math.pow; // required for unqualified use of the name pow
public class Test{
public static void main(String[] args){
double x = 5 pow 6; // equivalent to pow(5,6)
double y = 2 Math.pow 4; // equivalent to Math.pow(2,4)
Vector v = new Vector(x,y);
Vector w = new Vector(y,x);
Vector result1 = v cross w; // equivalent to v.cross(w)
double result2 = v dot w; // equivalent to v.dot(w)
Vector result3 = 3 scale v; // see note below
Vector result4 = w scale 4; // equivalent to Vector.scale(4)
}
}

Note: It's fairly obvious how "w scale 4" becomes "Vector.scale(4)" – in fact it could even become "w.scale(4)" if it existed. However, it's less obvious how "3 scale v" should be handled. The left operand is a primitive type, so name lookup of scale is first performed in the current scope (including static imports!) – a static method taking arguments double, Vector is required. It is not found (hopefully), so the right operand is examined. It is not a primitive type, so a method is sought in the Vector class, and it is found. So "3 scale v" becomes the method call "Vector.scale(3,v)".

It would probably be even better if "w scale 4" became "w.scale(4)" and "3 scale v" became "v.scale(3)". While this would be no harder to implement, it would cause a few potential problems. The scale method should be able to determine whether its argument was originally the left operand or the right operand, since it could make a difference in the result (it doesn't in this scenario, but it could in other situations). How to do that? I can't think of a good way. Maybe a second boolean parameter or something which is automatically filled in when it is called... though that makes it harder to use the non-operator syntax on it.

The best way I can think of just now is to define a method $scale which assumes its argument was a right operand, and have the operator resolution mechanism favour that method when the reference type is the right operand (or the reference type of the left operand does not define the required operator), if it exists. However, that requires the user to declare methods with the $ character in it. I'm not quite sure if that could conflict with names generated by the compiler (which usually have a $ sign somewhere to avoid name conflicts; for example $VALUES in an enum type).

> 1.1.1: double d = sin(x);
You marked sin as an operator too – I think it would not make sense to do so, really. But if it were an operator, the syntax would probably be "sin x" rather than "sin(x)".
>
> 1.1.2 is more like a scripting language and is just
> plain bad. One could argue that instanceof is an
> example of a similar operation so why not make a
> general mechanism for such an operation.
I don't get how it is "just plain bad". It could make complex expressions containing BigIntegers or matrices or vectors or other similar types actually readable.

> PRO:
> 1.b. Code becomes 'cleaner', loss of package, class
> qualifiers, loss of () brackets.
You haven't lost the parentheses at all. In fact, this method requires more use of parentheses then C++ style overloading because there is no defined precedence between the operators. You've lost the function call parentheses, but they will inevitably be replaced with many grouping parentheses.

As for package and class qualifiers, you already gave an example showing how they are not lost.

> 1.2.2: double p1 = x PreciseMath.pow 4;

Unless I misunderstand what you mean?

> CON:
> 1.i. Extra keywords
There's little wrong with extra keywords. Especially when it's just [i]one[/i] extra keyword.

> 1.k. More variations of the same refactoring
> methods.
I don't get what you mean?

> 1.l. Code becomes more difficult to read. What
> happens when you have two things with the same name.
You're wrong. Code would become [i]easier[/i] to read. However, you're right that if there were two operators with the same name it could be confusing. But then, couldn't you say the same for two methods of the same name? Example:

class One {
public Two jump(One who);
}

class Two {
public One jump(Two who);
}

One o = new One();
Two t = new Two();
o.jump(o).jump(t).jump(o);

That's just as confusing as:

o jump t jump o

> 1.m. operator precedance becomes an issue.
Yes, it does. The easiest way to solve it would be to issue a compiler error (or warning) for expressions that depend on the precedence of user-defined operators. You could also add a mechanism to define precedence on a per-operator basis, but that leads to more issues and is likely not worth it.

> ------- type 2: improve functional conventions
>
> We allow the prefix of any type declaration with
> another class. static 'operator' methods in said
> class are available as methods of the variable type
> provided that the first parameter of said function is
> the primitive type that should be passed into the
> said method.

It's not a bad idea, but it only works in declaration statements. What if you have an expression statement? Under this proposal, the following would not be able to be made to work at all:

int x = 7;
x = x.pow(4); // Syntax error: cannot invoke pow() on the primitive type int

If you integrated this idea into the statement labelling syntax, though, it could work.

int x = 7;
operator FuzzyMath: x = x.pow(4);

Note the keyword operator in the label – that's required to distinguish it from a regular label. It would be possible to use a different choice of keyword, of course. For example "import" might be a more appropriate choice.

> PRO:
> 2.a. Makes more "methods" available for use on
> primitives.
This is nice, but minor.

> 2.b. Standard convention/interpretation is line by
> line easier to understand and easier to understand.
Well, I'm not so sure. What if you wanted to calculate the quadratic formula? For reference, it's the following:

(-b +/- sqrt(b^2 - 4ac) / 2a

int a=3, b=4, c=2;
operator Math:
( -b + (b.pow(2) - 4*a*c).sqrt() ) / (2 * a)

That's not any clearer than the following:
( -b + sqrt(pow(b,2) - 4*a*c ) / (2 * a)

> 2.c. Generalise the usage of Integer, Double and
> assorted primitive Object counterparts.
Elaborate please?

> 2.e. doesnt 'hide' the type far from the declaration
> of the variable.
Huh? What do you mean by this?

> 2.f. applies to both primitives and objects and gets
> reduced to a method at compile time.
Ah, so it applies to objects too. So, using my Vector example earlier, you could have the following?

Vector v = new Vector(3,4);
double n = 3;
operator Vector:
Vector result = n.scale(v);

> CON:
> 2.i. Can you have more than one prefixing type? X Y Z
> x = 10.
I'd say that's probably a bad idea. But yeah, you could allow it/

> 2.j. What happens when you've two or three classes
> with either conflicting method names?
Same as when you import conflicting names, I expect.

> 2.k. Doesnt introduce operators.
Which is a problem, since it doesn't solve the readability issues inherent in a lack of operators.

> 2.l. have to use a different variable placeholder
> when your you want to use a different set of prefix
> operator helper classes. X Y Z double x = 1.1; X Y E
> double x1 = x;
I think my ammendment (the label thing) solves this, because you no longer have to declare a variable to use the feature. You would still have to break it into two lines, though:

operator X Y Z: double x = 1.1.sin();
operator X Y E: x = x.pow(43);

> ------- type 3: overload restricted unused operators
>
> Use #, $ as operators for programmatic use.

Good idea, but I don't think it'll work well. First of all, $ is not an available symbol (it forms part of an identifier token). Second, there is a very limited number of ASCII characters that are not otherwise used (# and ` are the only ones, actually). Of course, if you allow any Unicode character that's not an indentifier character, then it could work. Still, I agree with you that it's not the best choice. In fact, it would actually not be operator [i]overloading[/i] – it would be giving the programmer the ability to [i]define[/i] new operator symbols.

> CON:
> 3.i. Naming conflicts with duplicate overrides.
Uh... what?

> ------- type 4: overload unused operators as per C++
>
> As per C++
Oh, [i]so[/i] descriptive!

C++ allows you to overload almost all of its operators. I'd hardly call that overloading "unused" operators!

> CON:
> 4.i. Difficult to read apps.
Wrong. Provided that the overloaded meaning it similar to the built-in meaning, it actually [i]improves[/i] readability of code.

> 4.j. Difficult to support IDEs.
Uh... what on earth do you mean by this?

> 4.k. No MAJOR benifit other than syntax changes.
I'd say that the increase in code readability is a major advantage. Or are you arguing that it's pointless because "a.add(b)" is just as readable as "a + b"? Yes, that's true – for trivial expressions there is no advantage to using operators. But suppose you wanted to calculate the quadratic formula, as above, but with BigIntegers. You would write it as follows (more or less – I didn't actually look up the BigInteger method names):

sqrt(pow(b,2).subtr(a.mult(4).mult(c))).add(b.neg()).div(a.mult(2))

With C++ style operator overloading (Or Python-style, which is even better) it becomes this:

( -b + sqrt(pow(b,2) - 4*a*c ) / (2 * a)

Now tell me, which is more readable? I doubt you'll pick the first one!

> ------- type 5: overload unused operators with
> restrictions
>
> As per C++ but we limit operators and limit this to
> word operators.
> PRO:
> 4.a. Freedom with safety.
>
> CON:
> 4.i. Mightaswell support operators to its fullest for
> reasonable feature closure.
> 4.j. If word operators are supported, see instanceof
> generalisation above.
> 4.k. If symbol operators are supported,
> 4.l. No MAJOR benifit other than syntax changes.
This is not really a proposal. You haven't given any information about what you mean!

> ------- type 6: standard language extension
>
> Propose a MyClass.javam standard that creates a
> public single class per .javam file. Said file
> contains a Math extension suited for an expression
> language.
>
> Language extensions would not modify or affect .java
> code. Outputs of .javam would integrate with normal
> java code as per normal
>
> PRO:
> 6.a. Freedom and clarity of meaning in "expression
> java".
> 6.b. Does not affect the clarity of normal java
> code.
> 6.c. Integrates as standard java classes without
> modifying the syntax of standard java.
> 6.d. No JVM changes.
>
> CON:
> 6.7. Another 'language'.
> 6.8. Suited for math expressions, possibly ONLY
> suited for math expressions.
I think the cons outweigh the pros here. But note:

> 6.b. Does not affect the clarity of normal java
> code.
The other proposals, particularly the first, also don't affect the clarity of Java code if you choose to use the standard syntax rather than the special operator syntax.

In summary, I like type 4 best, but would be almost as happy with type 1. I think type 2 is also an interesting idea that could possibly work alongside either 1 or 4.

Message was edited by: celticminstrel (Sorry, didn't notice that this was an ancient topic...)

kcpeppe
Offline
Joined: 2003-06-15

> need multiple arguments (Monika already mentioned min
> and max). They need to be written in method-style. So
> why not handle all in method-style, even the
> single-argument functions like sin?

Sorry, I should have addressed this in the last post.

with sin, you are querying an object. With min or max, you are asking for cooperation between a set of objects. In the former why not just ask the object. In the later, you may want some container (class object???) to coordinate the interactions between the object. That way the objects don't have to have a sense of order themselves (which is most likely a good thing).

>
> --
> My 0.02 EUR
> Tom

kcpeppe
Offline
Joined: 2003-06-15

>
> One counter example could be VB. But VB became
> successful because of a great IDE and not because of
> the language's simplicity.
This is actually a great point.... because does this mean we should shift our focus from language to tools? Isn't language the ultimate tool?

vhi
Offline
Joined: 2004-10-11

It is not necessary that everything has to be centered around the language. In case of Java, the language is the main tool. Other tools are woven around Java. Compare it with VB where independently, VB language is not of much worth. But used with IDE, it is good. Java, independently, is very powerful. IDEs simply increase the power of Java. IMHO, if Microsoft had released VB as-it-is in the beginning without the IDE, it would not have been picked up. People bear with the quirks of VB because it is a good development environment.

>> because does this mean we should shift our focus from language to tools? Isn't language the ultimate tool?
Yes. The reason is that a good tool is much more valuable than simply a good language. I do agree that we need good languages so that we can code with confidence. But, most of the development work is rather mundane, repetitional. Therefore, a language must have hooks so that tools can easily work with it. That is the reason why a good component architecture, versioning scheme, features like annotations etc are more important than how a while/for loop is written. Syntaxes that are pleasing for the eyes are good for small examples, but when it comes to large scale development, tool-friendliness is more important.

tsinger
Offline
Joined: 2003-06-10

> Ok, this maybe a matter of taste but to me
> angle.sin() makes much more symantic sense than
> Math.sin( angle) because.. that is what you are
> doing, asking an angle for it's sin.

Hmm, when you are writing a mathematical equation, do you also think in the OO-style? Or do you just write "a = sin alpha"? But there are also functions, which need multiple arguments (Monika already mentioned min and max). They need to be written in method-style. So why not handle all in method-style, even the single-argument functions like sin?

--
My 0.02 EUR
Tom

kcpeppe
Offline
Joined: 2003-06-15

> > Ok, this maybe a matter of taste but to me
> > angle.sin() makes much more symantic sense than
> > Math.sin( angle) because.. that is what you are
> > doing, asking an angle for it's sin.
>
> Hmm, when you are writing a mathematical equation, do
> you also think in the OO-style?
I always think OO like ;) and have for many years.

Or do you just write
> "a = sin alpha"? But there are also functions, which
> need multiple arguments (Monika already mentioned min
> and max). They need to be written in method-style. So
> why not handle all in method-style, even the
> single-argument functions like sin?

well sin shouldn't need any arguments and method style.... message style... I don't think that really matters.. what matters is the reciever of the message/method call in one case is a class and in the other is an object. I vote for objects being recievers.

>
> --
> My 0.02 EUR
> Tom

murphee
Offline
Joined: 2003-06-10

You didn't say how you would implement or how you would like to use min,max, or other functions that need arguments.

chakrayadavalli
Offline
Joined: 2004-08-16

Yes, Static methods do have a place in Java and it is the last place to look at when developing and API that has bigger user base.

For instance, when you approach the problem of finding the min of two integers a and b, one would be quick to write Math.min(int...). But it would make sense to have something like new Sequence(int...).min(). That way, one could easily implement different algos to deal with a particular case.

Now you may say, why create a new object?! My answer: Dont worry about it. If you do, then you are better off with assembly.

angben
Offline
Joined: 2004-10-07

I have been thinking lately that the way to add operator overloading to Java would be to do it in the IDE. What I mean is, have the source code on disk show the convoluted, 'normal' syntax. Then, in the source code editor, allow the user to write as if operator overloading exists. Annotations like you suggest (@operator) would help the IDE know what overloaded operators are available.

So I can write: a + b + c in my IDE to add three matrixes, but the IDE is really doing a.add(b).add(c) or whatever. Perhaps the IDE would highlight these translated areas in a special way and allow me to quickly toggle between the 'syntactical sugar' form and the 'as it really is' form.

That way you get the ability to understand what is really going on and work at the higher level. Everything downstream from the IDE (e.g. the compiler) would simply be unaware that you were using the sugar.

Anyways, my two cents. Annotations are going to make Java evolve faster than it has in the past. Things the Java langugae folks refuse to add (const) are going to be added through annotations (@const) by the user community. This will probably mean a great deal of loss of control for how the language evolves, but I don't think that's necessarily a bad thing.

tomia
Offline
Joined: 2003-06-13

I can't see the benefit of it. When coding formulars I want to read them as natural as possible, without using such constructs.
The solution for me would be a language support with operators for the Number-Types.
I never understood why String has an +-operator but BigDecimal doesn't.

Thomas

tim12s
Offline
Joined: 2004-02-02

While I disagree with the feature being added to Mustang and if it were, i disagree with the proposed method. Considering other alternatives to how Operator overloading would work...

I personally prefer type 6 and type 2.

------ type 1: generalise instanceof

We generalise the instanceof operator for programmatic reuse.

public operator double sin(double angle);
public operator double pow(double x, double exponent);

1.1.1: double d = sin(x);
1.1.2: double p = x pow 4;

1.1.1 is already achievable.
1.1.2 is more like a scripting language and is just plain bad. One could argue that instanceof is an example of a similar operation so why not make a general mechanism for such an operation.

PRO:
1.a. Generalise the instanceof mechanism.
1.b. Code becomes 'cleaner', loss of package, class qualifiers, loss of () brackets.
1.c. code gets reduced to a method call at compile time

CON:
1.i. Extra keywords
1.j. Extra parsing overhead and complexity.
1.k. More variations of the same refactoring methods.
1.l. Code becomes more difficult to read. What happens when you have two things with the same name.
1.m. operator precedance becomes an issue.

PreciseMath {
public operator double pow(double x, double exponent);
}

FuzzyMath {
public operator double pow(double x, double exponent);
}

Say we dont import the mechanism.

So our syntax becomes

1.2.1: double d = FuzzyMath.sin(x);

1.2.2: double p1 = x PreciseMath.pow 4;
1.2.2: double p2 = x FuzzyMath.pow 4;

1.2.2 is just plain ugly. It mightaswell have been,

p2 = FuzzyMath.pow(x,4).

------- type 2: improve functional conventions

We allow the prefix of any type declaration with another class. static 'operator' methods in said class are available as methods of the variable type provided that the first parameter of said function is the primitive type that should be passed into the said method.

FuzzyMath {

2.1.1: public operator double sin(double angle);
2.1.2: public operator double pow(double x, double exponent);

}

2.2.1: FuzzyMath double x = 6.22;
2.2.2: FuzzyMath double e = 4.0;
2.2.3: FuzzyMath double r = x.sin();
2.2.4: FuzzyMath double v = r.pow(e);

As you can see, the X in x.sin() is passed into the static method as the first argument. By default, all methods in the Integer, Double, String, etc classes should follow this convention. String (to some extent) already does because its an object.

PRO:
2.a. Makes more "methods" available for use on primitives.
2.b. Standard convention/interpretation is line by line easier to understand and easier to understand.
2.c. Generalise the usage of Integer, Double and assorted primitive Object counterparts.
2.d. parsing follows functional syntax.
2.e. doesnt 'hide' the type far from the declaration of the variable.
2.f. applies to both primitives and objects and gets reduced to a method at compile time.

CON:
2.i. Can you have more than one prefixing type? X Y Z x = 10.
2.j. What happens when you've two or three classes with either conflicting method names?
2.k. Doesnt introduce operators.
2.l. have to use a different variable placeholder when your you want to use a different set of prefix operator helper classes. X Y Z double x = 1.1; X Y E double x1 = x;

------- type 3: overload restricted unused operators

Use #, $ as operators for programmatic use.

3.1.1. int x = a # b;
3.1.2. int x = a $ b : c ;
3.1.2. int x = a $ b : c ;

Dont know what you want from this...

PRO:
3.a. You know its custom defined.

CON:
3.i. Naming conflicts with duplicate overrides.
4.j. No MAJOR benifit other than syntax changes.

------- type 4: overload unused operators as per C++

As per C++

PRO:
4.a. Freedom for math applications and bad developers.

CON:
4.i. Difficult to read apps.
4.j. Difficult to support IDEs.
4.k. No MAJOR benifit other than syntax changes.

------- type 5: overload unused operators with restrictions

As per C++ but we limit operators and limit this to word operators.

PRO:
4.a. Freedom with safety.

CON:
4.i. Mightaswell support operators to its fullest for reasonable feature closure.
4.j. If word operators are supported, see instanceof generalisation above.
4.k. If symbol operators are supported,
4.l. No MAJOR benifit other than syntax changes.

------- type 6: standard language extension

Propose a MyClass.javam standard that creates a public single class per .javam file. Said file contains a Math extension suited for an expression language.

Language extensions would not modify or affect .java code. Outputs of .javam would integrate with normal java code as per normal

PRO:
6.a. Freedom and clarity of meaning in "expression java".
6.b. Does not affect the clarity of normal java code.
6.c. Integrates as standard java classes without modifying the syntax of standard java.
6.d. No JVM changes.

CON:
6.7. Another 'language'.
6.8. Suited for math expressions, possibly ONLY suited for math expressions.

Message was edited by: tim12s
added type 6.

patrikbeno
Offline
Joined: 2004-10-11

[b]type 1[/b]

[b]1.1.2[/b]
- Better that operator overloading as we know it.
- better [i]a add b add (c mul a) add b add (c div 2)[/i]
than [i]a.add(b).add(c.multiply(a)).add(b).add(c.divide(new BigDecimal(2)))[/i]

[b]1.i.[/b] no extra keywords, @operator would be annotation supported by the compiler
[b]1.j.[/b] minimal, same as +*/ & co. operators. If it is not operator, it must be imported operator function
[b]1.l.[/b] in (a div b) div is statically imported. It can safely be like this: (a MyOps.div b Another.div c)
[b]1.m.[/b] solvable: http://forums.java.net/jive/thread.jspa?messageID=3818#3251

Whole thing is a reaonable syntactic sugar. Nothing more.

I agree that if you cannot use static imports, readability suffers. But you have a choice and conflicts can be solved.

you can use @operator Number div(Number n1, Number n2)
as you wish:

a div b // proposed operator syntax
div(a,b)
Utils.div(a,b)

It is ordinary method for which compiler provides special support.
You can have public operator functions in a shared utility class, or you can have private operator function in your local class, whatever...
freedom of choice

[b]type 2[/b]
- Just doesn't impress me. You call methods on object that does not define them,
- More parsing problems than with simple proposed syntactic sugar that expands (a div b to div(a,b)).
- plus CONs you mentioned

[b]3-5[/b] just NO

[b]6[/b] I might be too tired now, I just don't get what it's all about. can you give an example?

draccagni
Offline
Joined: 2003-06-16

I confirm [b]type 1[/b] always the best!

D.

draccagni
Offline
Joined: 2003-06-16

I think it is a great idea : it permits a high readability of the code. I hope 4 Mustang :-)

D.

kcpeppe
Offline
Joined: 2003-06-15

a = b div c is very readable and in fact... follows a Smalltalk style of syntax that I'm very happy with. That said, Java has gone off in a different direction and I'm not happy with increasing the amount of syntax that is present in the language for the sake of coolness or reverting back to what once was. There seems to be some useful changes that we could make instead of adding to our syntactic woes.

For example, as good as a lot of the JDK code base is (and it is pretty good), we have a horrible code smell in the JDK code base. java.lang.Math is final and static. That smells like a garbage can to me. It's a class where we dump a lot of things that don't have a home and.. it's true.. the functions there take the place of a math library and really have everything to do with functions and not much to do with OO. The problem is, the place where you'd put the behavior in an OO system are all exposed to us as primitives. It would seem much more useful to blend primitives with object so that we can eliminate the duel system and be able to rid ourselves of the garbage can.

Cheers - Kirk Pepperdine

monika_krug
Offline
Joined: 2004-10-14

Not everything needs to be OO, static methods have their use, too, and Math is good example for this.
double angle = PI/2;
double sinValue = Math.sin(angle);
is more sensible than
double sinValue = angle.sin();

Even better example: min and max.
double min = Math.min(a, b); makes sense,
double min = a.min(b); makes no sense.

Monika.

kcpeppe
Offline
Joined: 2003-06-15

> Not everything needs to be OO, static methods have
> their use, too, and Math is good example for this.
> double angle = PI/2;
> double sinValue = Math.sin(angle);
> is more sensible than
> double sinValue = angle.sin();

Ok, this maybe a matter of taste but to me angle.sin() makes much more symantic sense than Math.sin( angle) because.. that is what you are doing, asking an angle for it's sin. In the other case, you are asking a third party to evaluate sin. Much less polymorphic and relies more on overloading. But maybe it's just me ;)

Again, this is a matter of taste and mine is for the latter.

On the question of OO. It's an interesting comment that I thought was settled in 93. The inherent advantages of OO over other methodologies has for ever changed the industry. It is an abstraction that has proved very useful. That said, it would appear that not everyone gets it which is ok. This is not to say that for one to execute useful work one needs OO. But experience has shown us that if one can apply OO, then one can certainly be more effective.

And certainly languages go a long way to supporting this view. If I look at what it took to build a fully distributed system even just 10 years ago over what it takes to get the job done today, then it is clear that having supporting abstractions available in the language has been an important productivity boost. Developers have run away from C++ not because of it's lack of usefulness, it is useful. They have run to languages that offer simplicity. You don't have to believe me, go and look at the number of VB components and the numbers of .NET developers (primarily VB). Java is simple.. maybe not as simple as it could be but it is (or has been up till now) been a fairly simple language to learn and use. It is also powerful in that it has allowed developers to be successful in ways that the may not have been able to be if they were to build the same types of systems in C++.

IMHO, the mesage is clear, we need to reduce complexity in the language, not increase it. Thus we need to reduce the level of syntax and make the compiler work for us. Development shops have mostly rejected C++ so why are we chasing it?

As for static methods.... it seems strange to have one set of methods that run with-in a context and another that do not.... The keyword this should always have context no matter where you are. Case in point, the factory pattern was originally designed to handle remote calls to a constructor. A high level solution to a low level problem. Need I say more!

vhi
Offline
Joined: 2004-10-11

Java took the path of native types because of one important thing: performance. And regarding the issue of simplicity, Objective C is much more simpler than C++ (only one syntactic addition to C). Smalltalk, I have heard is simple. But, considering the popularity of development languages, C++ has the edge. The reason is, many developers are willing to forgo syntactical simplicity for some other advantages (speed and compile-safety). The reason Java took off is that it is much safer than other languages, if not faster.

One counter example could be VB. But VB became successful because of a great IDE and not because of the language's simplicity. If the language simplicity was the issue, then BASIC should have been more popular for *professional* development than C.

kcpeppe
Offline
Joined: 2003-06-15

> Java took the path of native types because of one
> important thing: performance.
Please don't confuse interface with implementation. Smalltalk also uses primitives they are just not exposed in the language. The do not have an underlying oop, instead the value is contained in an immediate direct. This is one place where the compiler and the VM can work for us.

And regarding the issue
> of simplicity, Objective C is much more simpler than
> C++ (only one syntactic addition to C). Smalltalk, I
> have heard is simple. But, considering the popularity
> of development languages, C++ has the edge.
Certianly the drive towards Smalltalk was killed by the emgergence of Java. But I think that this is because Java looks more familiar to the average developer than Smalltalk does and people expect typing. With Java they get what they expect and I'm sorry to say with Smalltalk they don't.

> One counter example could be VB. But VB became
> successful because of a great IDE and not because of
> the language's simplicity. If the language simplicity
> was the issue, then BASIC should have been more
> popular for *professional* development than C.

I agree that IDE played a role in the popularity of basic. That said, there was a lot of basic being developed before VisualStudio came into being. Take QuickBasic for example.

VB is extremely popular amoung professional developers. Take a quick look at the component market. It is full of VB components. I dare say they have much richer choises than we do in Java and I dare say that Java has many more choices than any other language/environment that I've worked in.

jarouch
Offline
Joined: 2004-03-04

> Please don't confuse interface with implementation.
> Smalltalk also uses primitives they are just not
> exposed in the language. The do not have an
> underlying oop, instead the value is contained in an
> immediate direct. This is one place where the
> compiler and the VM can work for us.

Do you know/have some benchmark results comparing Smalltalk and other languages? I saw some on Internet and Smalltalk was always aprox. 10 times slower..

Btw if you want just pose as if primitive is object and internaly it is still primitive, how would you handle such things like synchronization on them for example?

brucechapman
Offline
Joined: 2004-03-18

I too am both averse to blanket c++ style operator overloading yet think that somewhere there is an acceptable solution.

This seems like a promising candidate.

You talked about static importing and then said
[code]a div b instead of a.div(b)[/code]
which isn't treating div as static. Did you mean
[code]a div b instead of div(a,b)[/code]?

With regard to the priority issue, I agree this is best done as a fixed value, rather than letting the operator specify its priortity.
there are 3 options
Highest (higher than ++)
Lowest (lower than =, += and friends)
In the middle somewhere.

Highest doesn't seem right, nor does making it lower than = :) so it needs to be somewhere in the middle. Consider this
[code]int i=1;
int j = 3 add i++;[/code]
if operators were lowest this would be [code](j = 3) add (i++);[/code]and if they were highest it would mean [code]j = (3 add i)++[/code]
Clearly neither of these is sensible.

As a suggestion, I would say, almost lowest, below ternary operator ( ?: ) but above assignment operators (= += >>>= and friends).

These operators would be left associative, that is [code]a opr b opr c == (a opr b) opr c[/code]