Yes, operator overloading can definately give room for confusing code. I would like it just for my own types (i.e. no changing the behavior of the build in classes), and even then one would have to be very careful when using the feature. Also, JavaDoc would help alot I think. It’s not something I miss alot, but something that would be useful sometimes.
You would have to fix Generics to allow primitive types and do away with type erasure. You also would have to worry about extended classes. Overriding the add operator could throw in some odd behavior, and even if you made an exception to prevent overriding those methods you might want to make the entire class final just in case one method relies on another. Then for human compile time checks, you lose the ability to glance at an expression and say “That looks like the method signature of this type of function, therefore its reasonable the code has this type of semantics.” I don’t want to have to scroll around, check if I’m working with primitives or Objects, find every variable declaration, parse the expression, determine which overloading methods get called, mentally convert from infix notation to postfix notation, double check the meaning of each overloaded method just to make sure their are no quirks in the semantics of that operation, trace through the return values and side effects of each operation, then make a different mental map that’s basically the same as the multi-line procedural format.
At the same time you lose the ability to easily make sense of arithmetic expressions. It’s faster to look at an expression with familiar order of operations as in ordinary algebra. You could still overload + for concatenating and not lose anything because its obvious, behaves differently, and can’t be used with other operators without conversions or parentheses. When it comes to most things, though, the use of operators tell me something useful about how primitives are being used and the use of explicit function calls tells me something useful about the way objects are being used. Mix the two, and certain blocks of code will force you to break your train of thought even if its shorter than the other version in some cases. Think of the line a = b * c;
Now you have to figure out if this is a scalar-scalar multiplication, scalar-matrix multiplication, scalar-vector multiplication, matrix-matrix multiplication, vector cross product, vector dot product, or something else entirely. Then a * b
may not necessarily even be close to b * a
and may be defined in two different places. `a = 0 * b[/t] does not necessarily mean a stores something like zero. It wouldn’t be too hard, but, as Java is now, you don’t currently need to methodically and roboticly parse code or learn how entire libraries work inside and out. It’s like untangling headphones. Not impossible, but a huge productivity killer. Although it would be nice to use operator overloading with things similar BigInteger and BigDecimal and more efficient software implementations of types with different levels of precision than built in primitives, its not worth the trade.
quick question, am I the only one around which do not think that type erasure is bad, but quite ellegant.
About operator overloading, everybodz here seems it can be bad if others use them but will not if only them use them in their own code. Why not use same Scala function classes in your Java code. One can mix Java with Scala code in the same applications with no problems(little changes to your build configuration) and Scala is an ideall language to build your own Domain Specific Language where you can overload as much you want and what you want.
PS: seems as if java-gaming.org is not banned in china, so I can at least access on of my most visited sites
I think type erasure was a great solution to get something that looked a bit like templates working backwardsly compatible with existing Java bytecode. It has its flaws and foibles but the way I use it it’s all good. I especially like the new <> shortcut in Java 8.
Cas
Operator overloading I see as necessary (even mandatory) if you are designing new types.
I see that many of the complaints being posted here can be solved by something external to the coding language: Project coordination.
No, seriously, I see this on a daily basis at work, powerful tools have dangerous implications (like a chainsaw), and when you have a room full of chainsaw-wielding maniacs, you need some proper structure if you want to get anything accomplished (And before they start chopping each other down).
Of course, then the question is… What is the goal of Java? If it is meant to be used exclusively as a high level language, then by all means all these dangerous bits would need to either be locked, or made available through some advanced API (much like JNI).
If, on the other hand, we want to integrate low level capabilities… Well, you can’t make a chainsaw without the saw.
(Yes, I’m State-The-Obvious-Boy, sidekick to Captain Obvious, I know) :
Type erasure only exists because it didn’t require changes to the verifier. The sad thing is that the verifier was being changed anyway (and was in the next version of java). Type refinement is very not fun with type erasure…well type erasure adds yet-more boilerplate and hacky work-arounds. What up-side is there (other than it pushed it out the door a little earlier)? I can’t think of any.
Operator overloading: Forget everything you think you know if you’re opinion comes from C++. Getter/setters are the one most important that java could use and would need to be VM aware (aka not-just sugar). Other stuff is sugar and you can just slap it on top yourself.
I actually like how Getters/Setters are handled in C# (Properties). Way more elegant and intuitive.
Personally I’d do explicit getter/setters via annotations for java. Future possibilities include interop with muli-dimensional array, concrete arrays, etc.
(Oh yeah, needs to be VM aware cause it would suck otherwise…simple example changing a public field to a getter/setter. Code using would need to be recompiled with identical source to work…that would be too horrible).
Using getters and setters everywhere is a symptom of not really understanding OOP though. Not that I want to spell it out but: if you’re going to all the trouble of hiding the implementation of a class by making all of its member data private, and then expose it all with trivial getters and setters, what exactly have you achieved. Nothing much apart from a lot of typing, and you’ve also managed to expose the entire internal state of your class as public API which means you can no longer change what’s under the hood without breaking everything that uses it.
So for the love of whoever you want to love, keep getters and setters to the bare minimum required for tool interop (eg. Javabeans*)
Cas
- haha, as if anyone uses them
I even see that by tighter view, no point in having a set of getter and setter for a field.
The advantage of getter and setter Methods is that you can make
a nice documentation, wich pops up in your IDE.
Together with explanations about what it is for, what to excpect, specific boundaries etc.
This is helpful when using a class again after a long time.
Ok, documentation works also with a field, but it add some security for
allowed parameter ranges.
/**
* set the love contained in this entity
* only values 0 to 8 are allowed
* -1 will throw a "You are so rude" Exception
* @param loveCount
*/
public void setMyValue(int loveCount)
{
..bla
}
I hear that spouted over and over. However the 99% of getters and setters out there in the wild do no such validation and never will. They are a total waste of time and space and effort.
Use a dot, if you’re simply passing properties as data around for such things as configurations. It is what a dot is for.
Cas
Yes, javadoc is my one true love! Pity I’m the only one using it in my team. :clue:
Getters and Setters have their uses, but it does rub me the wrong way when a class has lots of them protruding like half-formed appendages.
I don’t use trivial getter/setter and like Cas…just say no. But they’re not the only kind (hidden composed data, disassociated data, data views).
There’s nothing really wrong with type erasure per se – even Haskell uses erasure – but the problem is that Java lets you use a raw type with nothing more than a warning. The spec says that a later version of the Java language could remove this ability, but we all know the score: nothing ever gets removed from Java, especially now that a lot of programs have come to depend on this behavior.
Scala works around erasure a lot of the time by generating and passing manifests at compile time, but there are still things manifests can’t fix, like overloading or pattern matching on List vs List.
It does mean you can’t do something like implement Multiplyable<Matrix>
and Multiplyable<Double>
(Big or small ‘D’ double…) in the same class. (I wish I could think of a better example, but this is the only non-obscure, non-trivial example that comes to mind.)
Trivial type erasure boilerplate example: I want to do this: return this;
and not abstract T self();
implemented here and there as return this
and always have to do return self();
I’d like strings to auto-initialize as “” instead of null.
I have been racking my brains for days trying to think of something I dislike about Java to post on this thread, but I can’t think of anything. The language is fine - generics took a bit of getting used to, but they are a great feature. If generics had been built into the language from the outset, they would probably be done differently without some of the limitations mentioned in this thread - but don’t forget that many of the early Java features had serious flaws and needed major rebuilding (threading, AWT etc) - so adding generics at a late stage may actually have given us a more mature and workable system.
It would be nice if Java had some built-in vector types to make use of SIMD instructions.
Oh well, generics… nice for simple usage cases like collections. But for anything complex when done correct and completely it leads to unreadable verbose code.