How do I overload += in Julia? - overloading

I'm trying to understand how operator overloading works in Julia. The manual is quite brief, and gives +() as an example function, then states all the operators are overloadable with their obvious names (a list of non-obvious names is also provided).
But what about +=? The function +=() doesn't even seem to exist, nor does +=!() (since it is a modifying function). I frequently overload operators in C++ by defining += first and then use a simple + based on copy and +=.
In my case I don't even think I need +, just the behavior of +=... I realize I could write my own modifying function but the operator syntax would be nice. (Out of curiosity, how do *=, /=, $=, etc work?)

There is no += function. It is simply syntactic sugar for a = a + b.
It is also not mutating. So a += b calculates a + b and then changes a to refer to the result. This means there is memory allocation for the result of a + b.

Related

Overloading operator without having a class

Can we use operator overloading on non-objects? e.g adding two vector<int>. Or do I need to make a class having vector<int> and then overload the + operator.
Also, I want to know if it is possible to have 2 different types of operands in a binary operator. If yes, how?
Can we use operator overloading on non-objects?
Operators are essentially implemented as functions and can accept a similar range of types as functions do.
There are a few restrictions, in particular, it is limited by the fact that at least one argument must be a class or enum (user or library type).
In addition, there are some operators that have to be implemented as member functions, so they will be associated with a class, but many can be declared and defined outside of a class.
The exact number of arguments is determined by the operator being implemented. Unary operators accept 1 argument, binary operators accept 2 arguments.
Generally, the advice is to offer behaviour similar to the canonical forms, but the language itself does not limit your implementation to just that behaviour.
Also, I want to know if it is possible to have 2 different types of operands in a binary operator. If yes, how?
Yes. Again, just as functions do.
Can we use operator overloading on non-objects? e.g adding two vector.
I think you meant to ask whether it's possible to use operator overloading outside of a class definition. And yes, it definitely is possible as already stated by other people here. Here's a simple example of overloading the '+' operator for a custom 'MyClass' type:
MyClass operator+(const MyClass& a, const MyClass& b)
{
return MyClass(a.value + b.value);
}
However, there is a reason why std::vector doesn't have overloads for arithmetic operators as the result is ambiguous. Do you want '+' to link two vectors together or should the components be added? How do you handle vectors which differ in size? Often, containers of the STL provide special methods for these purposes and don't rely on operators when it's not clear so make sure you've checked the specification of std::vectors
You're free to implement such operators as you see fit, especially with your own types but you risk creating unintuitive behaviour and ultimately, bad code. In the case of std::vector, it might be better to write a function with a descriptive name which operates on std::vector in the way you desire:
std::vector<int> addComponents(const std::vector<int>& a, const std::vector<int>& b);
Can we use operator overloading on non-objects? e.g adding two vector[?]
The premise of your question is broken, because a vector<int> is an object.
Overload all you like.
Also, i want to know if it is possible to have 2 different types of operands in a binary operator.
Try it.
If yes, how?
By typing it.

overload "->" (member access) recursively

I am learning how to overload "->" and the documentation says that:
"operator-> is called again on the value that it returns, recursively, until the operator-> is reached that returns a plain pointer. After that, builtin semantics are applied to that pointer."
While it is clear what the documentation says, essentially that an overloaded "->" of a class could use itself a "special pointer" having itself an overloaded "->" that could give a "special pointer" etc etc until a "plain pointer" is found, I cannot find an example of a real use of it ( unless it is used to find a linked list last element ).
Could somebody explain what is the retionale behind the scenes, ( as that possibility isn't provided with "plain pointers" - so I dont' see any reason to provide it with "special pointers" ).
An example of real world use could help too, as probably I am missing a model where to apply the behaviour.
On the opposite side there could be the need to avoid that behaviour, how could it be done ?
Well, the -> operator works under rater special circumstances.
One can call it a pseudo-binary operator. According to its natural syntax pointer->member it takes two operands: a normal run-time operand on the left-hand side and a rather "strange" member name operand on the right-hand side. The "strangeness" of the second operand is rooted in the fact that C++ language has no user-accessible concept for representing such operands. There's nothing in the language that would express a member name as an operand. There's no way to "pass" a member name through the code to the user-defined implementation. The member name is a compile-time entity, remotely similar to constant expressions in that regard, but no constant expression in C++ can specify members. (There are expressions for pointers-to-members, but not for members themselves).
This creates rather obvious difficulties in specifying the behavior of overloaded -> operator: how do we connect what was specified on the right-hand side of -> (i.e the member name) to the code written by the user? It is not possible to do it directly. The only way out of this situation is to do it indirectly: force the user to channel the user-defined functionality of the overloaded -> operator into the functionality of some existing built-in operator. The built-in operator can handle member names naturally, through its core language capabilities.
In this particular case we have only two candidates to channel the functionality of the overloaded -> to: the built-in -> and the built-in .. It is only logical that the built-in -> was chosen for that role. This created an interesting side-effect: the possibility to write "chained" (recursive) sequences of overloaded -> operators (unwrapped implicitly by the compiler) and even infinitely recursive sequences (which are ill-formed).
Informally speaking, every time you use a smart pointer you make a real-world use of these "recursive" properties of overloaded -> operator. If you have a smart pointer sptr that points to a class object with member member, the member access syntax remains perfectly natural, e.g. sptr->member. You don't have to do it as sptr->->member or sptr->.member specifically because of the implicit "recursive" properties of overloaded ->.
Note that this recursive behavior is only applied when you use operator syntax for invoking the overloaded -> operator, i.e. the object->member syntax. However, you can also use the regular member function call syntax to call your overloaded ->, e.g. object.operator ->(). In this case the call is carried out as an ordinary function call and no recursive application of -> takes place. This is the only way to avoid the recursive behavior. If you implement overloaded -> operator whose return type does not support further applications of -> operator (for example, you can define an overloaded -> that returns int), then the object.operator ->() will be the only way to invoke your overloaded implementation. Any attempts to use the object->member syntax will be ill-formed.
I cannot find an example of a real use of it ( unless it is used to find a linked list last element ).
I think you're misunderstanding what it does. It isn't used to dereference a list element and keep dereferencing the next element. Each time you call operator-> you would get back a different type, the point is that if that second type also has an operator-> it will be called, which might return a different type again. Imagine it being like x->->->i not x->next->next->next if that helps
An example of real world use could help too, as probably I am missing a model where to apply the behaviour.
It can be useful for the Execute Around Pointer pattern.
On the opposite side there could be the need to avoid that behaviour, how could it be done ?
Call the operator explicitly:
auto x = p.operator->();

Operator vs functions behaviour

I am reading through the following document,
https://code.google.com/p/go-wiki/wiki/GoForCPPProgrammers
and found the statement below a bit ambiguous:
Unlike in C++, new is a function, not an operator; new int is a syntax error.
In C++ we implement operators as functions, e.g. + using operator+.
So what is the exact difference of operator vs function in programming languages in general?
The actual distinction between functions and operators depends on the programming language. In plain C, operators are a part of the language itself. One cannot add an operator, nor change the behavior of an existing operator. This is not the case with C++, where operators are resolved to functions.
From a totally different point of view, consider Haskell, where ANY (binary) function may be treated as a binary operator:
If you don't speak Haskell, but know about dot products, this example should still be fairly straight-forward. Given:
dotP :: (Double, Double) -> (Double, Double) -> Double
dotP (x1, y1) (x2, y2) = x1 * x2 + y1 * y2
Both
dotP (1,2) (3,4)
and
(1,2) `dotP` (3,4)
will give 11.
To address the quote in the Go documentation: The Go developers are simply stressing that where in C++, one would treat new as a keyword with its own syntax, one should treat new in Go as any other function.
Although I still think the question is basically a duplicate of Difference between operator and function in C++?, it may be worthwhile to clarify what the difference means in the specific context you quoted.
The point there is that a function in C++ is something that has a name and possibly function arguments, and is called using this syntax:
func(arg1,arg2,...)
In other words, the name first, then a round bracket, then the comma-separated list of arguments. This is the function call syntax of C++.
Whereas an operator is used in the way described by clause 5 of the Standard. The details of the syntax vary depending on the kind of operator, e.g. there are unary operators like &, binary operators like +, * etc.; there is also the ternary conditional operator ? :, and then there are special keywords like new, delete, sizeof, some of which translate to function calls for user-defined types, but they don't use the function call syntax described above. I.e. you don't call
new(arg1,arg2,...)
but instead, you use a special "unary expression syntax" (ยง5.3), which implies, among other things, that there are no round brackets immediately after the keyword new (at least, not necessarily).
It's this syntactic difference that the authors talk about in the section you quoted.
"What is the difference between operators and functions?"
Syntax. But in fact, it's purely a convention with regards to
the language: in C++, + is an infix operator (and only
operators can be infix), and func() would be a function. But
even this isn't always true: MyClass::operator+() is
a function, but it can, and usually is invoked using the
operator syntax.
Other languages have different rules: in languages like Lisp,
there is no real difference. One can distinguish between
built-in functions vs. user defined functions, but the
distinction is somewhat artificial, since you could easily
extend lisp to add additional built-in functions. And there are
languages which allow using the infix notation for user defined
functions. And languages like Python map between them: lhs
+ rhs maps to the function call lhs.__add__( rhs ) (so
"operators" are really just syntactic sugar).
I sum, there is not rule for programming languages in general.
There are simply two different words, and each language is
free to use them as it pleases, to best describe the language.
So what is the exact difference of operator vs function in programming languages in general?
It is broad. In an abstract syntax tree, operators are unary, binary or sometimes ternary nodes - binding expressions together with a certain precedence e.g. + has lower precedence than *, which in turn has lower precedence than new.
Functions are a much more abstract concept. As a primitive, they are typed subroutine entrypoints that depending on the language can be used as rvalues with lexical scope.
C++ allows to override (overload) operators with methods by means of dynamically dispatching operator evaluation to said methods. This is a language "feature" that - as the existence of this question implies - mostly confuses people and is not available in Go.
operators are part of c++ language syntax, in C++ you may 'overload' them as functions if you dont want the default behaviour, For complex types or user defined types , Language may not have the semantic of the operator known , So yuser can overload them with thier own implementation.

subscript operator postfix

The C++ standard defines the expression using subscripts as a postfix expression. AFAIK, this operator always takes two arguments (the first is the pointer to T and the other is the enum or integral type). Hence it should qualify as a binary operator.
However MSDN and IBM does not list it as a binary operator.
So the question is, what is subscript operator? Is it unary or binary? For sure, it is not unary as it is not mentioned in $5.3 (at least straigt away).
What does it mean when the Standard mentions it's usage in the context of postfix expression?
I'd tend to agree with you in that operator[] is a binary operator in the strictest sense, since it does take two arguments: a (possibly implicit) reference to an object, and a value of some other type (not necessarily enumerated or integral). However, since it is a bracketing operator, you might say that the sequence of tokens [x], where x might be any valid subscript-expression, qualifies as a postfix unary operator in an abstract sense; think currying.
Also, you cannot overload a global operator[](const C&, size_t), for example. The compiler complains that operator[] must be a nonstatic member function.
You are correct that operator[] is a binary operator but it is special in that it must also be a member function.
Similar to operator()
You can read up on postfix expressions here
I just found an interesting article about operator[] and postfix expression, here
I think it's the context that [] is used in that counts. Section 5.2.1 the symbol [] is used in the context of a postfix expression that is 'is identical (by definition) to *((E1)+(E2))'. In this context, [] isn't an operator. In section 13.5.5 its used to mean the subscripting operator. In this case it's an operator that takes one argument. For example, if I wrote:
x = a[2];
It's not necessarily the case that the above statement evaluates to:
x = *(a + 2);
because 'a' might be an object. If a is an object type then in this context, [] is used as an subscript operator.
Anyway that's the best explanation I can derive from the standard that resolves apparent contradictions.
If you take a close look to http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B it will explain you that standard C++ recognize operator[] to be a binary operator, as you said.
Operator[] is, generally speaking, binary, and, despite there is the possibility to make it unary, it should always be used as binary inside a class, even because it has no sense outside a class.
It is well explained in the link I provided you...
Notice that sometimes many programmers overload operators without think too much about what they are doing, sometimes overloading them in an incorrect manner; the compiler is ease is this and accept it, but, probably, it was not the correct way to overload that operator.
Following guides like the one I provided you, is a good way to do things in the correct manner.
So, always beware examples where operators are overloaded without a good practice (out of standard), refer, first to the standard methods, and use those examples that are compliant to them.

operator overloading c++

When overloading operators, is it necessary to overload >= <= and !=?
It seems like it would be smart for c++ to call !operator= for !=, !> for operator<= and !< for operator>=.
Is that the case, or is it necessary to overload every function?
Boost operators might be what you are looking for. These will derive most of your operators based on a few fundamental ones.
That C++ does not provide this automatically makes sense, as one could give totally different meanings to < and >, for example (although it would often be a bad idea).
I am going to take a minority viewpoint here. If you already use boost then using boost operators is not that big of a deal. It may be the correct and tested way to do things but adding boost dependency just for the operators is an overkill.
It is possible to write complex C++ programs without boost (which I personally find aesthetically unpleasant) and so to Keep It Simple (Stupid), to answer OP's question, if you overload operator ==, you should also overload operator !=. Same is true for <, >, ++ etc.
Yes, it is necessary, if you want all of them to work the way you want them to work.
C++ does not force any specific semantics on most of the overloadable operators. The only thing that is fixed is the general syntax for the operator (including being unary or binary and things like precedence and associativity). This immediately means that the actual functionality that you implement in your overload can be absolutely arbitrary. In general case there might not be any meaningful connection between what operator == does and what operator != does. Operator == might write data to a file, while operator != might sort an array.
While overloading operators in such an arbitrary fashion is certainly not a good programming practice, the C++ language cannot assume anything. So, no, it cannot and will not automatically use ! == combination in place of !=, or ! > combination in place of <=.
No, you only need to overload operator == and operator <, the standard library will take care of the rest :)
(EDIT: see using namespace std::rel_ops ;)
Yes it is necessary to overload whichever operators you want to be used as you define them - C++ will not make the decision you describe above; however, keep in mind that if the reason you are overloading is to sort your class, than you only need to override the operators used by the sort routine. In the case of the RTL sort algorithm you only need to override < and =.
Yes! They are each technically different operators. C++ compilers are not inherently inference engines, they are parsers/compilers. They will only do as much as you say to do.
http://www.parashift.com/c++-faq-lite/operator-overloading.html, http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
There are a few shortcuts you can use, such as CRTP to get them automatically injected (see the various Compare classes) into your class.
C++ does not, as a language, define any operator in terms of any other overloaded operator. Just because you have operator+, doesn't mean you get operator+= for free (unlike Ruby and Scala). Just because you have operator < and == doesn't mean you get <= for free. Just because you have operator == doesn't mean you get != for free (unlike Ruby and Scala). Just because you have unary operator * (unary) doesn't mean you get operator -> for free.
std::relops (if imported correctly) and provide default definitions, and Boost provides some mix-ins that define all of the comparison operators in terms of < and ==.
You can use overloading to use user defined names.
Operator overloading means using the same operator to do perform operation on different items which are not in that category. Function overloading means using the same name of function but different arguments, so as to overcome the overhead when the same function is called during looping.