Please create an account to participate in the Slashdot moderation system

 



Forgot your password?
typodupeerror
×
Java Programming

Overloading and Smooth Operators 75

An anonymous reader writes "IBM DeveloperWorks has an interesting article on operator ad hoc polymorphism (operator overloading for the uninitiated). With the increase in Java popularity and their banning of operator overloading (among other things) the author decides to show some of the great benefits that operator overloading can bring, as long as it is served with a 'healthy dose of caution.'"
This discussion has been archived. No new comments can be posted.

Overloading and Smooth Operators

Comments Filter:
  • Useful? Doubtful. (Score:5, Insightful)

    by crow ( 16139 ) on Wednesday October 26, 2005 @03:03PM (#13883168) Homepage Journal
    Sure, there are lots of things you can do with operator overloading, but there are good reasons to avoid them. Ultimately, it comes down to some basic questions:

    Will the use of overloading operators...

    *) reduce developement time?
    *) reduce the number of bugs?
    *) improve maintainability?

    In most cases, the answer is at best murky. Sure, if you're doing mathematical programming, adding complex numbers, rational numbers (tracking numerators and denominators instead of using floats), or something like that, then it's intiutively a good thing. But in most cases, it's not intuitive. When someone else comes to the project and tries to figure out what's going on, it's like having a bunch of extra macros for them to look up. Function calls make it much more obvious what's going on.
    • by keesh ( 202812 )
      Sure. Because Complex x = (a + b) * c; is so much less readable than Complex x = (a.add(b)).assign(c); .

      Java disallowing C++-style constants, operator overloading, templates and everything else useful just adds to the theory that Java is C++ for stupid people.
      • that's why the parent said that for complex numbers, matrices, etc, operator overloading is the right thing to do.
      • Which is why I've always called Java "C++ for VB programmers."
        • Are you trolling or do you just like to make sweeping, overgeneralized statements?
          • It is not a "sweeping, overgeneralized statement" to state how I explain my opinion of Java to people. If you have a different opinion of the language, that's fine. This one is mine. It would be sweeping and/or overgeneralizing if I was stating fact. I was obviously not stating fact, but giving my opinion.
        • Funny, it seems like there are very few actual C++ positions that are not Windoze/MFC positions. So if you want to be a Windoze Weenie, stick with C++/Visual C++ . Sure there's lots of C++ positions around, that don't pay, developing on platforms like KDE and GTK, the the paying positions seem to be few and far between.

          Personally I want to get paid to code, and I don't want to code for or on Windoze, so I use Java.

          I've also the garbage C++ code produced on the *NX platform. People want to move to Java

    • Re:Useful? Doubtful. (Score:3, Interesting)

      by bluGill ( 862 )

      Will the use of overloading operators... *) reduce development time? *) reduce the number of bugs? *) improve maintainability?

      If the answer is yes to the above (This is an all or nothing test), then use them, if not don't use them.

      There is a good reason that most examples of operator overloading are complex numbers - using overloaded operators for complex numbers reduces development time, reduces the number of bugs, and improves maintainability.

      There is a good reason examples of operator overloading n

      • Operator overloading is often abused.

        That's what I keep hearing, but I've never actually seen anywhere dubious usage of it, such as your "circle + square" example.
        • That is because you are used to the cout << foo; syntax, so you don't think of it as abuse. Though it can be argued that there is no better way, I don't know if I buy that.

    • Will the use of overloading operators...
      *) reduce developement time?
      *) reduce the number of bugs?
      *) improve maintainability?
      In most cases, the answer is at best murky.

      Then it follows that avoiding operator overloading is subject to the same test. That's not an argument against operator overloading.

      I've seen lots of sucky C++ code, and operator overloading has never been one of the problems -- maybe because sucky C++ code tends to be written by either C or Java programmers ...

    • I think the problem with overloading in languages like C++ and Groovy is that they only allow you to overload existing operators. If you use a more advanced language like Fortran (in any recent standard such as F90/F95/F2003) you find that you can invent your own operators. If, for example, you want a fuzzy matching operator (similar to LIKE in SQL for example) then you can call it .like. - no need to overload == or something that has not quite the right name. If you want set operators no need to overl
  • by GaelTadh ( 916987 ) * on Wednesday October 26, 2005 @03:06PM (#13883188) Homepage
    Contrary to the article that states that a++ and ++a can be aliased to one call a.next() this is not how it should be done:
    a++ needs to return the value of a BEFORE it is incremented
    ++a needs to return the value of a AFTER it is incremented
    Sorry for the rant, I've just spent too long working with programmers that didn't know the difference
    (Not at my current job mind you ...)
    • I'm not sure exactly what he is saying. I think he is saying that with groovy you HAVE to use a.next().. Which is stupid.
    • my first thought was "Hey there's a difference!", too.. until I realized that the call to a.next() is equivalent to the ++ part:

      ++a : call a.next() and evaluate a

      a++ : evaluate a and call a.next() then.

      and I think we can agree that sane programs should use the same operator overloading for ++ in both cases.
      • Sure but the call for a++ should be { b = a; //Creates a copy ! a.next(); return b; } and ++a { a.next(); return a; } //No copy created
  • CustomObject1.multiplyBy(CustomObject2.subtract(Cu stomObject3.raisedTo(10)))

    or

    CustomObject1 * (CustomObject2 - CustomObject3 ^ 10)

    • You are making the false assumption that languages either support operator overloading, or restrict operators to the predefined basic set. This is simply not true.

      Languages of the ML family, for example, permit the definition of arbitrary new operators, they just don't permit you to overload existing operators. This means that when you see +, you know it will be adding two numbers, not concatenating two collections or whatever. But if you want an operator to concatenate your collections, you can define o
  • Operator overloading is too easy to abuse because others won't necessarily understand what a + or - or x, etc. means. I think this post says it all:

    -= cobnet -= wrote:
    >
    > Now I wonder why Java doesn't allow overriding of operator, because I think
    > it makes things a lot easier...
    >
    > For example... presume you have written a class Point() and that you test
    > this class:
    > Point p1 = new Point (2,3);
    > Point p2 = new Point (46,4);
    > Point p3 = new Point (5,8);
    > Point p4 = new Point (5,
    • When did you last take a Physics class? Adding points (or non-C++ vectors) is a very, very common thing.

      It's extremely useful for solving, i.e. the following two problems.
      • You have four masses of 1 kg each, at (0,3), (2,-1), (4,0) and (2,7). Where is your center of mass?
      • John, Jude and July are walking home from work. John lives one block north of his workplace. Jude lives two blocks north and one block east of John. July lives four blocks west of Jude. How many blocks east, and how many blocks north,
      • Adding points (or non-C++ vectors) is a very, very common thing.

        I'm not disagreeing with you, per se, but this is true only for vanishingly small values of common.
        • It's common for physics programming. And some of the largest computing projects in the world are all about physics.

          That's one of the main reasons why huge clusters get built...to perform simulations and process physics data.
          • Yeah, I understood that part, and I don't disagree that it's common within certain fields - just that the entire field is esoteric when you consider the programming community at large. You said "very, very common" initially, which I'd personally reserve as a description for something like, say, concatenating strings.

            To make a car analogy (why the hell not... it seems like a good one) it's kind of like saying bumping another car is a common technique (the word 'technique' is important to my meaning). From
            • Point taken, chewed and swallowed.

              I still think it's useful, though I can't come up with any examples not solvable by other methods. But the nice thing about C++ is, like Perl, There's More Than One Way To Do It.

              Also, I don't think a language should be designed around keeping a stupid programmer or project team from shooting themselves in the foot.
              • Also, I don't think a language should be designed around keeping a stupid programmer or project team from shooting themselves in the foot.

                I definitely agree with you there. It's not like the 'eye on safety' in Java has prevented people from writing some of the ugliest code on earth.
              • Also, I don't think a language should be designed around keeping a stupid programmer or project team from shooting themselves in the foot.

                Well, all languages are designed with some safety features, like type checking. There really isn't anything wrong with different languages designed for not only different problems, but different skill levels. When Java was introduced it was touted as the language "for the rest of us". That's fine, not everyone has a CS degree and wants to get down to the C or C++ level. D
        • "vanishingly small values of common"? Just because it's not in 'Learn Java in 21 Days" doesn't make it exotic. Every game, graphics routine, audio/video codec, and more touch on vectors.
    • by Anonymous Coward
      Adding two points together makes absolutely no sense.

      No, it doesn't. And you'll note that this has nothing to do with operator overloading. Without it, he's still doing p2.add(p3), which is equally meaningless but more verbose.

      OTOH, if you have to do, say, fixed point math in J2ME, you end up with code that looks like the bastard child of Lisp and Perl.

      There are many wrong places for operator overloading, but it's indispensible for the right places.
    • Adding "points" in 2d is the same as adding compex numbers. The only problem with his example was that he didn't call his "points" vectors.
    • I suppose you've never done any sort of complicated 3d or other sorts of geometry programming?

      Frankly, having point/matrix/quaternion/plane/etc classes with reasonably chosen operator overloading allows me to condense a LOT of code into quite little, with as far as I can tell a general *increase* in legibility.

      When I started doing 3d programming, for robotics simulation, I used a typedef'd float[4] for vertices, and float[16] for matrices. I had C functions for adding, dot products, cross products, matrix m
  • Hours can be easily wasted if someone redefines something in a way that isn't expected. Especially dinks who make macros so "save time".
  • Like any tool (Score:4, Insightful)

    by RingDev ( 879105 ) on Wednesday October 26, 2005 @03:42PM (#13883476) Homepage Journal
    Used poorly, it results in crap. But does that mean that we should block off entire development tool from programmers?

    A properly designed and applied overloaded operator can be a great tool for development.

    A poorly designed or inappropriatly applied overloaded operator can create a mess of code and a maintenance nightmare.

    Now, replace "overloaded operator" with a blank and fill it in with what ever you like. "data layer", "abstract class", "architexture", etc... But if the powers that be decide that programmers need to be protected from data access, inheritance, and design fundamentals, what the hell are we left with?

    -Rick
    • Re:Like any tool (Score:3, Insightful)

      by AuMatar ( 183847 )
      But thats the design theory of Java. I'm not saying I agree with it, but there it is. For example- why no pointers in Java? THey're useful in many situations, and by a competent user they are no more bug prone than any other method. But Java disallows them to protect you from the idiot programmer.

      If you want an OO language that doesn't try to hedge the coder in with rules for his own good, you aren't programming in Java. You're using C++. If you don't care for inheretance and templates, you may even
      • Re:Like any tool (Score:3, Insightful)

        by RingDev ( 879105 )
        True, but a poorly designed overloaded operator can result in confusing/buggy code. A poorly designed pointer math function can result in overwriting memory that belongs to some other process.

        Its one thing to protect an environment from a stupid coder. Its another to protect a stupid coder from themselves.

        -Rick
  • The author refers to an older article about Groovy. He does not really say what it is, but it seems to be new scripting language. The Groovy interpreter is a java program. Which means that the JRE is interpreting an interpreter.

    I have heard before that performance is no longer relevant, but I have seen few designs that take this opinion so serious :-). I wonder whether it is faster than my first BASIC interpreter on the CPC: about 700 floating point for loops per second, and much more in integer...
    • by Shelrem ( 34273 ) on Wednesday October 26, 2005 @04:16PM (#13883751)
      You're entirely wrong. Groovy is another language that targets the JVM. Groovy is either compiled to Java bytecode (and from there, JIT compiled to machine code by the JVM), or it's compiled at runtime in a JIT fashion. There is no interpreter written in Java that runs Groovy code. Groovy is just another language that targets the JVM.

      The benefit from all this is that in Groovy, you can interface to Java classes with literally no overhead. It's a brilliant idea for a new language because all the libraries are already there! This skips past one of the biggest stumbling blocks for new lanaguages.

      All in all, Groovy's a pretty interesting language that's worth looking into, but apparently you can't be bothered to do a Google search.
      • You're entirely wrong. Groovy is another language that targets the JVM. Groovy is either compiled to Java bytecode (and from there, JIT compiled to machine code by the JVM), or it's compiled at runtime in a JIT fashion. There is no interpreter written in Java that runs Groovy code. Groovy is just another language that targets the JVM.

        This is indeed a good way to integrate seamlessly with Java.

        Jython takes the same approach with Python (Python source is compiled to Java bytecodes) to allow tight Java integra
      • Have looked at Groovy. Its been around for years, and still hasn't delivered on what's promised. Its all hype, and pretty useless for anyting non-trivial.

        Check JRuby [sourceforge.net] for the 90% solution.

  • As long as we're limited to few characters that are overloadable, this leads only a short way. What about this: Leave the operators as they are because they are useful (or let people overload them if they don't work as desired) but allow for defining new operators. This is just matter of syntax. You write "x=y+z" instead of "x=add(y,z)". So why not
    content >>>> home @ host, *) proto=UDP, *) markas=BULK;
    Allow for defining completely arbitrary syntax that way. Sometimes constructs imposed by the la
    • That's exactly what I was thinking.

      Unfortunately I know that there exists no language (it might be possible in some scripting languages) that has such a feature. Perhaps when I get around to finishing MODL2 (my own damn language, the second) I'll add in not just operator overloading, but operation definition.

      Example custom operators that would be useful:

      • Scope resolution ( :: ) for runtime polymorphism
      • Member of ( . and -> ) for runtime polymorphism
      • Function ( () ) for arbitrary argument order and na
      • Unfortunately I know that there exists no language (it might be possible in some scripting languages) that has such a feature. Perhaps when I get around to finishing MODL2 (my own damn language, the second) I'll add in not just operator overloading, but operation definition

        Most languages with real (not preprocessor) macro support (notably LISP, Scheme, Dylan) support this.
        • Since neither Lisp, Scheme, nor Dylan (in its Lisp form anyway) support operators at all your statement is curious. By which I mean, untrue. Now it's true that Common Lisp supports read-macro characters. But AFAIK it does _not_ support read-macro characters which extend the parser in a non-LL fashion so as to provide inline operators. That is, you can't make a read-macro called + which can be called like this: a + b. Because 'a' has already been parsed, evaluated, and completed. Oh, sure you can hack
    • by Anonymous Coward
      Leave the operators as they are because they are useful (or let people overload them if they don't work as desired) but allow for defining new operators. [...] Allow for defining completely arbitrary syntax that way.

      As usual, there already is a language that allows this, and (as usual) it's called Lisp. :-)

      First, in Lisp, + is not a special case in the syntax: it's the name of a function, like anything else. If you want to define a function called *#@!*, there's nothing stopping you. (You can name them pr
      • As usual, there already is a language that allows this, and (as usual) it's called Lisp. :-)

        The unique specialness of an operator is that it may exist in a non-LL form, typically to provide infix notation. This is what makes an operator different from a function. But the defining feature of Lisp's syntax is that it is LL. It seems to me that by definition Lisp cannot support operator overloading. Sometimes Lisp is not the answer to any question foo.

    • Haskell allows you to define new operators. It works very smoothly and makes it easy to implement concise domain specific languages. As another poster points out, Lisp also (sort of) has this feature, although this is more because it doesn't have infix operators at all. (Note to pedantic Lispkinks: yes, you could extend Lisp using reader macros etc. to add infix operators, but you really wouldn't want to, would you?)
      • Yeah. This is one of the things I'd like to see OCaml (my primary language of choice) steal from Haskell. It's got the ability to define new operators as well, but it's not nearly as flexible in that area as Haskell (without having to pull out the camlp4 hammer).

        Meh. I really need to do more Haskell coding.
  • Blech (Score:2, Insightful)

    by VGR ( 467274 )
    From the article:

    a <=> b ..................... a.compareTo(b)

    Yeah, that's a lot more readable.

    This is precisely why operator overloading is both unneeded and unwelcome. Like an earlier post said, the benefit doesn't even come close to outweighing the price. "<=>" is a perfect, classical example of how programmers get positively drunk with freedom and treat operator overloading like a shiny new toy. Code full of that instead of "compareTo" is an instant eyesore. I'd rather spend my ti

    • Yeah, that's a lot more readable.

      Well yeah, actually, it is. Take a look at the kind of domain specific mini-languages that have been developed on top of Haskell and more recently C++. For example, the Spirit parser library for C++ which is part of Boost. Once you start composing complex expressions, infix operators are virtually required to make the end result anything close to readable. Haskell is a big win over C++ in this respect because (apart from all the advantages it has as a functional language)

  • by david.given ( 6740 ) <dg@cowlark.com> on Wednesday October 26, 2005 @06:09PM (#13884653) Homepage Journal
    Well, yeah, except when it doesn't...
    String a = "hello " + "world!";

    I love the smell of hypocrisy in the morning. It smells like... coffee.

    Seriously, operator overloading is a powerful technique that, done right, allows you to write clear, expressive, maintainable code. Done wrong it allows you to write foul spaghetti, but any language allows you to write foul spaghetti --- Flon's axiom: [sysprog.net] There does not now, nor will there ever, exist a programming language in which it is the least bit hard to write bad programs.

    Not allowing operator overloading (except when the language authors break their own rules) has no effect other than to reduce the options available to the programmer. It means that while you can't use them in cases where operator overloading is not useful, it also means that you can't use them in cases where operator overloading is useful and would produce better code. It means you can't, for example, create an imaginary number class that works the same way as int or long. This is not the mark of a good, extensible, expressive language.

    • Yes, that's the one exception. And one that one you should be very carefull with. Since Strings are immutable in Java, if you do "a" + "b" + "c", it will first create 3 Strings. Then it will add "a" and "b", creating a new String. Now *that* String will be formed into *another* new String by concatenating "c". That's quickly building up to the creation of a lot of String class instances. See "Effective Java" by Joshua Bloch.

      The String is a pretty ugly hack, and the "+" operator should never have been used f
      • Yes, that's the one exception. And one that one you should be very carefull with. Since Strings are immutable in Java, if you do "a" + "b" + "c", it will first create 3 Strings. Then it will add "a" and "b", creating a new String. Now *that* String will be formed into *another* new String by concatenating "c". That's quickly building up to the creation of a lot of String class instances. See "Effective Java" by Joshua Bloch.

        Except sometimes the compiler optimises this into creating a StringBuffer object,


      • Since Strings are immutable in Java, if you do "a" + "b" + "c", it will first create 3 Strings. Then it will add "a" and "b", creating a new String. Now *that* String will be formed into *another* new String by concatenating "c". That's quickly building up to the creation of a lot of String class instances. See "Effective Java" by Joshua Bloch.


        Well actually, almost all java compilers would convert:

        "a" + "b" + "c"

        into "abc"

        and "a" + s + "c"

        into

        new StringBuilder().Append("a").Append(s).Append("c"). ToString()
    • There does not now, nor will there ever, exist a programming language in which it is the least bit hard to write bad programs.

      Shouldn't this be that no language makes it any harder to write bad code than to write good code? I mean, it seems to me that it really is quite hard to write a bad program (which does something useful) in Intercal, bf, or optimal IA64 ASM...
  • If your programming language lets you use "+" for more than one numeric type, you use operator overloading. Unless you think adding fp numbers should use a different syntax than adding integers, you're a fan of operator overloading.

    An "Ask Slashdot" re the stupidest overloadings we've ever seen might be fun, but discussing whether the functionality is a good idea is absurd. Any discussion should center on when to use it, not whether to use it.
    • Back in the days, I could have endless discussions on C++ constructs. In C++ you can do almost anything, especially if you count in the preprocessor (and you have to, or #include won't work :). This makes for a very complex language. And although I miss the discussions, I am pretty glad I don't have to explain all this to the first new programmer that walks through the door. Because if it's there, people *ARE* going to use it. And even if you do understand it, the next programmer through the door won't unde
    • If your programming language lets you use "+" for more than one numeric type, you use operator overloading. Unless you think adding fp numbers should use a different syntax than adding integers, you're a fan of operator overloading.

      Interestingly, there are languages that do this. OCaml, for example, uses "+" exclusively for integers; for floating-point numbers, "+." is used instead.

      Now, OCaml's not a mainstream language, but it's reasonably popular as minor languages go. There's quite a few programmers ou
  • I cannot see *any* overloading in the examples that make sense. Comparing Lava lamps for size? The ugly shift Sting operator? And what happens if there is a "compareTo()" with an ugly side effect? Will the programmer really check out the implementation of '' like he might have done with the "compareTo()" method?

    I hate it when writers are trying to explain something, and then use the most awfull programming constructs to show you how to use the feature. Even if the bad code is unrelated, it still teaches the
    • Slashdot, don't try to be smarter than the author. If I want plain old text, *GIVE* me plain old text. That was obviously the "smaller than" operator I was talking about.
  • Security audits (or hell, any type of code audit) becomes a nightmare the more overloading and polymorphism a programmer uses. I HATE having to audit c++ code from even a moderately creative programmer. Honestly, the more of an OO language a programmer uses, the less verifiably secure it will be and it will be trusted less accordingly.
  • Write the overloading implementation as a series of proofs for interested field so that people can't make shit like << mean anything other than left-shift (multiply by power of two).

    For example, to overload "==" make the software implement a routine "comparitor" that returns a structure of public elements that the runtime resolves as comparison itself. To implement String's comparitor, have it return a structure like this: { int; byte[]; }

    The result is that the compiler can figure out how to compare t

Get hold of portable property. -- Charles Dickens, "Great Expectations"

Working...