Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the `unary_` prefix needed in scala?

Tags:

scala

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?

like image 267
jhabbott Avatar asked May 20 '13 07:05

jhabbott


People also ask

What is prefix in Scala?

Currently scala supports unary prefix operators ( - , + , ~ , ! ) for expressions (e.g., def unary_- ) and does not support prefix types.

What is Unary_ in Scala?

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_~


2 Answers

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_!.

like image 85
Jörg W Mittag Avatar answered Nov 07 '22 17:11

Jörg W Mittag


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.

like image 38
drexin Avatar answered Nov 07 '22 15:11

drexin