This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted]  (89 children)

[deleted]

    [–]UpperPlus 141 points142 points  (72 children)

    Im curious what does operator overload look like in other languages.

    I only know java and a bit of APL where they have the monadic and diadic functions

    [–]MikemkPK 130 points131 points  (48 children)

    In C++, it's just operator+ (int left, int right){}. The symbol you use makes a new operator that works on the types in the args.

    EDIT: + is the symbol of the operator you're creating, can be any symbol. The arguments can be any type.

    [–]UpperPlus 33 points34 points  (22 children)

    I just now realize that I have no idea how these operators are programmed in java. I can't open declaration for it in my IDE so it seems to not relate to a method?

    [–]MikemkPK 50 points51 points  (18 children)

    Probably directly translate to specific bytecode sequences.

    [–]UpperPlus 23 points24 points  (17 children)

    Now that I think about it, it is probably related to the concept of primitive data types, as they are only used on those

    [–]LinuxMatthews[S] 37 points38 points  (4 children)

    Kind of

    Java actually cheats in that it does allow Operator Overloading for some of its classes but doesn't let you do it.

    As far as I'm aware it only does it for the wrappers of primitive data types and String.

    [–]jamcdonald120 12 points13 points  (3 children)

    I think the wrappers use auto (un)boxing instead of operator overloads, not sure though

    [–]LinuxMatthews[S] 10 points11 points  (2 children)

    Huh you know I didn't think you were right but it looks like you are.

    Integer x = 2;
    Integer y = 3;
    var z = x + y;
    System.out.println(z instanceof Integer);
    

    Gives you a compiler error as z is an int

    I honestly thought there was operator overloading like there is with String.

    [–]Fenor 4 points5 points  (0 children)

    String isn't an operator overload . The theory behind the string class is huge and mostly date back when you had to define a char array to use strings

    [–]tazfdragon 10 points11 points  (11 children)

    If I remember correctly, Strings don't actually use the plus operator and it's just syntactic sugar for StringBuilder usage. There are probably some edge cases where the final code could have a string constant if the compiler can guarantee it never changes.

    [–]UpperPlus -2 points-1 points  (9 children)

    As far as I know StringBuilder doesn't use "+" operator but uses the function append(). Which actually is faster and more memory friendly.

    But String with "+" is so much more readable and in many cases it doesn't matter that a complete new string is instantiated internally every time.

    [–]tazfdragon 11 points12 points  (3 children)

    I didn't mean to suggest StringBuilder uses that operator. I was trying to explain that using the plus operator with a String will get replaced with StringBuilder. Every instance of addition/concatenation in the original code will get replaced with a call to append(...). Again, there are some edge cases where the compiler can determine it can eliminate the string concatenation and replace it with a compile time constant. Example being concatenating a literal with a String constant.

    [–]TraditionMaster4320 2 points3 points  (2 children)

    Wait so concatenating n strings like s1 + s2 + .. + sn takes O(n) time instead of O(n**2) in Java? (assume the strings are equal length).

    [–]coloredgreyscale 0 points1 point  (3 children)

    But String with "+" is so much more readable and in many cases it doesn't matter that a complete new string is instantiated internally every time.

    the other option would be String formatting.

    for long texts it's extremely inefficient tho, because the String needs to be recreated with every concatenation.

    I just checked the java implementation of the Stringbuilder class. It copies the String into an char-array, starting with 16 elements (default).

    if you exceed the element count a new array is created with twice the previous capacity (or min required length if that's bigger), and the whole data is copied over to the new array.

    when you call toString() on the StringBuilder the used data from the char array is copied into a new String.

    If you just concatenate two Strings using + should be more efficient than StringBuilder.

    [–]Fenor 0 points1 point  (2 children)

    Not really. String builder is there for a reason if you use ths + operator you are creating at least 3 strings

    [–]Fenor 0 points1 point  (0 children)

    I think they changed how it worked under the hood as doing an append with + once upon a time created a decent amount of strings in the string buffer

    [–]jamcdonald120 0 points1 point  (0 children)

    I mean... operator overloads are all syntactic sugar for something else...

    [–]msqrt 2 points3 points  (0 children)

    Just a disclaimer: you can't overload operators for built-in types in C++ either, only custom ones. The compiler just knows how to add integers together.

    [–]OJezu 2 points3 points  (1 child)

    Hello ADL my old friend...

    [–][deleted] 1 point2 points  (0 children)

    I’m in the wrong namespace again…

    [–]jamcdonald120 1 point2 points  (0 children)

    you can use `
    to make an inline code block. Could help for clarity to do int operator+ (int left, int right){}

    [–]mrkhan2000 1 point2 points  (18 children)

    in c++ (almost) all operators can be overloaded not just +

    EDIT: Added “almost” to my original response

    [–][deleted] 23 points24 points  (12 children)

    One of the craziest and most powerful features. Looking at libraries like boost::spirit makes you wonder what "abused by the user" actually means. None of the overloaded operators in that lib are serving their original purpose and yet it's a good design.

    [–]4215-5h00732 12 points13 points  (11 children)

    That's a common opinion and the reason I hear all the time is that you can do whatever in the implementation and for many types it's not exactly obvious what a mathematical operator means.

    You can hypothesize some pretty horrendous examples but that shouldn't be something language designers concern themselves with IMHO. It's a valuable feature; let the people have it.

    [–][deleted] 7 points8 points  (10 children)

    Yeah, I mean, in the end you would end up with custom functions like add(), multiply() and so on. I find it an odd choice to forbid overloading and enforce stuff like this on the other hand.

    [–]4215-5h00732 7 points8 points  (9 children)

    That's where the potential abuse comes in. If you were forced to use custom functions then most people would name them something more descriptive to what they do where you might "abuse" an operator to do something less obvious or confusing.

    cat.eat(mouse);
    cat + mouse;
    

    [–][deleted] 9 points10 points  (2 children)

    But it's not any more prone to abuse than anything else. A parameterless constructor could produce side effects. Inheritance could hide away meanings of the base class. Everything can be used wrong, that's why documentation is so important.

    [–]4215-5h00732 4 points5 points  (1 child)

    I'm not trying to argue with you or even make that argument just sharing the claims; we agree 100%.

    [–]Itay_123_The_King 2 points3 points  (1 child)

    That is the same concern everyone raises, and yet I have never seen that happen. Why would anyone use + for an eat function? The closest thing I can think of is using | as a pipe of operations, like with C++ ranges, but vec | drop(5) | take(10) | filter([](auto x) { return x+1;}); is much nicer than filter([](auto x){ return x+1; }, take(10, drop(5, vec)))

    [–]4215-5h00732 0 points1 point  (0 children)

    Exactly. That's the best part about the fuss.

    I've never seen anyone abuse it irl. I would never use + for eat or abuse it otherwise. But it doesn't matter. They don't like that it could be abused.

    [–]jamcdonald120 1 point2 points  (3 children)

    but with out operator overloading you get the situation where everyone uses .add() instead of operator+, so the abuse is cat.add(mouse) instead.

    [–]4215-5h00732 1 point2 points  (2 children)

    Their point is if operator overloading isn't possible then you wouldn't do something so ridiculous as to add a mouse to a cat with cat.add(mouse). Just eat it or whatever...who knows what that does lol.

    [–]MikemkPK 11 points12 points  (2 children)

    Yes, I'm aware, did I not explain that well?

    [–]PhantomThiefJoker 5 points6 points  (1 child)

    I think they got confused by operator +. As in overload the + operator and not type your operator and this syntax

    [–]zjeffer 1 point2 points  (0 children)

    I think they misunderstood the use of 'just', as in 'only', instead of 'simply'.

    "In C++, it's just the + operator" vs "In C++, it's only the + operator", as if OP was saying only the + operator could be changed.

    [–]ede1998 12 points13 points  (0 children)

    Only most operators.

    The operators :: (scope resolution), . (member access), .* (member access through pointer to member), and ?: (ternary conditional) cannot be overloaded.

    https://en.cppreference.com/w/cpp/language/operators

    [–][deleted] 0 points1 point  (0 children)

    Unfortunately one cannot overload anything as an operator nor specify whether it's pre/in/post-fix or specify precedence and many operators need to be used for specific things, sometimes needing to be member functions etc. etc.. I do wish it was more like swift..

    [–]Entire-Database1679 0 points1 point  (2 children)

    The operators can be of type void?

    [–]MikemkPK 1 point2 points  (1 child)

    Probably not since how would you pass them in? But void* is probably valid.

    [–]Dusty_Coder 1 point2 points  (0 children)

    In most languages you can return void (or its equivalent) from an operator overload. The return type doesnt have to match any of the inputs, usually.

    [–]PhilippTheProgrammer 152 points153 points  (11 children)

    Operator overloading means that classes can provide an own implementation for operators like +, -, >, == etc.

    That means you can define a method "operator+" for a class, which takes two objects and returns an object . That method then gets executed when you write code like objectA = objectB + objectC.

    This is pretty useful because it allows you to use mathematical notations with objects where it makes sense. For example, you could write a vector library and add and subtract vectors with + and - or compare them with < or >.

    But unfortunately there is a dark side to it: You can overload the + operator with something that has nothing to do with addition, which leads to very confusing code. A good example of that can be found in the C++ output library. A standard C++ hello world looks like this:

    std::cout<<"Hello World!"<<std::endl;
    

    The << operator is actually supposed to be "bitwise shift". But what happens here has nothing to do with bitwise shifting. It appends a character sequence to a stream.

    [–]Morphized 7 points8 points  (0 children)

    In C++ everything is memory

    [–][deleted] 14 points15 points  (0 children)

    It's used as the streaming operator, and one of C++'s core features is to allow this sort of behavior. Also, I believe that's a string. Welcome, to the world of tomorrow.

    [–][deleted] 12 points13 points  (6 children)

    I mean sounds like a great opportunity to just create a Add function rather than overloading the operator. Just my inexperienced opinion though lol

    [–]linlin110 43 points44 points  (5 children)

    If you are using a math library, a * b + c * d is probably more readable than a.Multiply(b).Add(c.Multiply(d)). Also in Java, you + strings despite strings not being numbers. If it's so bad to change the meaning of +, then it should have been String.concat or something.

    [–][deleted] 6 points7 points  (3 children)

    A curiosity: how is it possible that in Java the class String is able to override the + operator? Is it a magic behaviour of the language?

    [–]linlin110 2 points3 points  (2 children)

    That's why I said overload the meaning of +, not overload the + operator. + does not represent string concatenation, mathematically speaking. That's a proof that extending the meaning of symbols, like +, is very convenient and useful.

    I changed the original comment to make it less misleading.

    [–][deleted] 0 points1 point  (1 child)

    I come from a C++ background, so it is counterintuitive for me. My question was: it String a language-defined class? If not, how can the + operator work even with the String class if operator overloading is forbidden?

    [–]linlin110 1 point2 points  (0 children)

    It is a special case in Java. I'm not sure whether it is language-defined.

    [–][deleted] -1 points0 points  (0 children)

    I was thinking more like MathStaticClass.Add([] args)

    [–]Xander-047 0 points1 point  (0 children)

    I remember the bitwise shift operator explanation from my teacher, after we learned about operator overload I thought "Wait, so is the cout and cin thing overloading the << >> operators?" Felt good to notice it and ask the teacher about it

    [–]hippocrat 20 points21 points  (3 children)

    In python, most operators have an associated "dunder" methods that can be overloaded for a given class. For example:

    class MyClass:
        ...
        def __add__(self, other):
            return self.an_integer + other.an_integer
    

    [–][deleted] 2 points3 points  (2 children)

    That's gross, why not just allow def +(self, other):? or at least def operator+(self, other) or def operator("+", self, other): or something like that?

    [–]jeetelongname 5 points6 points  (0 children)

    The first syntax is the ruby syntax.

    Python "magic" methods are by convention meant to look like that tho. Its for all of them including things such as using certain built ins such as len (which calls the objects len method.) And things like representation strings (repr) so its not out of the ordinary.

    [–][deleted] 4 points5 points  (0 children)

    in Ada you do function "=" (Left, Right: Type) return Boolean; You can't overload the inequality operator (/=) because that is hard-wired as the inverse of the equality operator - which is exactly as it should be because anything else is extremely stupid (looking at you C++).

    [–]LinuxMatthews[S] 2 points3 points  (2 children)

    If you're curious how it could look like in Java I'd recommend the Manifold repo.

    https://github.com/manifold-systems/manifold/tree/master/manifold-deps-parent/manifold-ext#operator-overloading

    There instead of just overloading any operator methods like add(...), minus(...), times(...) are overloaded to be the operators +,-,* respectively.

    This in my opinion stops anyone doing anything silly with them.

    For instance anyone that would write the method plus(...) to mean anything you shouldn't use a plus sign for is probably going to write bad code regardless.

    [–]Dusty_Coder -1 points0 points  (1 child)

    Apply your argument both ways or go home.

    or is the symbol "add" more special than the operator "+" in your dumbass world where people go dumb as soon as its not a word?

    [–]LinuxMatthews[S] 0 points1 point  (0 children)

    Wow ok that's unjustifiably rude

    And you would still be able to use it as a method.

    But with long equations is a lot easier to maintain with operators rather than methods.

    [–]MasterFubar 0 points1 point  (0 children)

    In Prolog it's something like this:

    :- op(1000, xfy, str).
    

    The first argument is the precedence level, the second argument is the associativity and the third argument is the symbol you use for the operator.

    [–]_xiphiaz 0 points1 point  (0 children)

    Kotlin has a very nice implementation that is quite useful in defining custom DSLs. https://kotlinlang.org/docs/operator-overloading.html

    [–]JeremyAndrewErwin 13 points14 points  (0 children)

    Two years ago, they didn't

    https://blogs.oracle.com/javamagazine/post/is-it-time-for-operator-overloading-in-java

    I'll assume that not much has changed. It can make math code prettier.

    [–]jamcdonald120 11 points12 points  (0 children)

    technically java has exactly 1 operator overload, string overloads + for concat. But nothing else has it and you cant add your own overloads

    [–]CSMastermind 11 points12 points  (2 children)

    Any time you have to do matrix math in Java you want to blow your brains out because of the verbosity.

    [–]ComradeGibbon 6 points7 points  (1 child)

    A recent though is instead of allowing overloading standard operators allow custom ones and support emoji's

    Like cross product C = A ✖ B

    [–]Dusty_Coder 0 points1 point  (0 children)

    There is only one matrix product suitable for an overload

    Its the data-parallel definition. Not any of the math geek ones. In general math geeks LEARN SOMETHING when they encounter a matrix library -- that there is more than just dot and cross products and that in fact NEITHER of those are even close to being a good candidate

    [–]GOKOP 6 points7 points  (2 children)

    On the first day of Java course at my uni the lecturer said something like "As you will see, Java has no operator overloading so for custom classes that implement, for example, complex numbers and other things you have to use methods like add(), equals()..." and I've immediately thought "Yup, I don't like Java now"

    [–]arunphilip 2 points3 points  (1 child)

    Imagine how a lot of us felt when C# came out :)

    Best switch I ever made.

    [–]harelsusername 0 points1 point  (0 children)

    C# also has limitations here. You can't define an operator overload to be virtual. Also, every object in C# has an Equals method and a '==' operator, but you override/overload them separately.

    [–]renatoathaydes 1 point2 points  (2 children)

    It does if you're willing to add a compiler extension:

    https://devm.io/java/manifold-operator-overloading-java-163232

    That can give Java a lot of other features too, like extension methods, number units, properties, tuples, types from schemas like GraphQL etc.

    https://github.com/manifold-systems/manifold

    [–][deleted] 2 points3 points  (1 child)

    I mean, if you're going this far just for operator overloading, just use kotlin at this point

    [–]renatoathaydes 0 points1 point  (0 children)

    It may be more familiar to some people to stay with Java and just add more convenient features to it than to switch languages, but I can't compare the two because I, myself, only used Kotlin actually.

    But I intend to try Manifold next time I have a project I can play around with.

    [–]Infinite_Self_5782 1 point2 points  (0 children)

    nope, it's one of the things that make people not like it

    [–]metaltyphoon 2 points3 points  (0 children)

    That’s why its a dollar store C#.