Beginner Scala question, but I couldn't find the answer on here.
Similar to overloading in C++, I would expect the compiler can tell the difference between a method called -
which takes one parameter (with the same type as the class) and the unary version of -
which takes no parameters, so why is unary_
needed?
Currently scala supports unary prefix operators ( - , + , ~ , ! ) for expressions (e.g., def unary_- ) and does not support prefix types.
The unary_~ method is utilized to return the bitwise negation of the specified int value. Method Definition: (Int_Value).unary_~ Return Type: It returns the bitwise negation of the specified int value. Example #1: // Scala program of Int unary_~
The unary_
prefix for unary prefix operators is a bit misleading: it's more about the prefix part than the unary part. You need some way to distinguish
!foo // unary prefix !
from
foo! // unary postfix !
Remember: Scala doesn't actually have operators. There are two ways to call a method, either with a .
or with whitespace:
foo.bar(1, "two") foo bar(1, "two")
And when you have a single argument, you can leave off the parentheses:
foo plus(1) foo plus 1
Lastly, (almost) any character is legal in an identifier:
foo plus 1 foo + 1
Now it looks like Scala has a binary infix +
operator, but it actually doesn't. It's just a normal method called with normal method calling syntax.
What I said above isn't fully true, however. If Scala didn't have support for operators and it all was just normal method calling, then
2 + 3 * 4
would evaluate to 20 (like it does in Smalltalk, Self and Newspeak for example) instead of 14. So, there is a little bit of support for operators in Scala (two little bits, actually). When a method is called with whitespace (so-called "operator syntax") instead of the .
, and that method starts with an operator character, then Scala will respect operator precedence.
And the other little bit of operator support is that there are some operators that you would like to have, but that cannot be easily expressed as a method call. It works fine for binary infix operators and unary postfix operators:
foo op bar // same as: foo.op(bar) foo op // same as: foo.op
But not for prefix or "around-fix" operators:
!foo foo(bar)
So, there are a couple of special syntactic sugar translation rules:
!foo foo.unary_! // same for +, - and ~ foo(bar) foo.apply(bar) foo(bar) = 1 foo.update(bar, 1) foo += 1 foo.+=(1) // but if this doesn't compile, then the compiler will also try foo = foo.+(1)
And the reason why there needs to be an underscore between the alphanumeric and the "operator" part in a method name is because you wouldn't know whether
foo!
means
foo.!
or
this.foo!
Thus, foo!
as a method name is illegal, it needs to be called foo_!
.
Because in scala it is totally fine to create a method named -
, that takes no arguments. How would you distinguish between a normal and a unary method? For example !
has a totally different meaning as unary, than as post fix operator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With