Why is Scala limited to just 4 prefix symbols?


#1

Scala supports only unary_-, unary_+, unary_! and unary_~ for prefix operators.
Is there a specific reason that only these 4 symbols are supported and not any special character combination like infix expression support?
Is anyone interested in Scala to support a generic unary_XXX definition?


#2

I’m willing to submit a SIP and implementation if more people are interested in expanding the prefix symbol vocabulary.


#3

I have a vague recollection that this was mentioned in a SIP meeting a couple months ago (while discussing the prefix types SIP), and that @odersky said something along the lines of “supporting those 4 prefix operators was a necessary evil, but we shouldn’t make the language worse by adding more of them”. I’m not sure whether that was picked up in the minutes, but maybe it was.


#4

Infix expressions are supported with every method, not just symbolic ones. Part of the appeal is that the rule is actually very simple: symbolic operators don’t work any differently than method names (save with precedence).

Unless there is a very compelling need, I do not favor increasing the distinction between symbolic and non-symbolic methods.

This has a clear use case, too. Suppose we have a condition that we want to express:

p

Now, suppose we want to say “not p”, i.e. invert the logic of the predicate. Well,

not p

would be a pretty obvious way to do it, wouldn’t it? Likewise, the English language order for a bunch of methods is opposite the order we need to invoke them, e.g. compare

"fish".reverse
reverse "fish"

But I think the advantages in parse regularity (for humans!) of a no-prefix-method scheme outweigh the advantage in being able to play word order typology games.

(Note that going from functions to methods is already a VSO to SVO transformation.)


#5

That’s interesting. Why would those 4 be more necessary than others?


#6

People like to use them with numbers (arithmetic and bitwise negation) and booleans (logical negation).

(I’m actually not sure what the point of unary_+ is. The spec says it is an identity function (section 12.2.1), but I’ve never seen anyone use it, and it’s not even implemented for BigInt ¯\_(ツ)_/¯ )


#7

Well, I’m guessing ! and - have clear arithmetical and logical usages. + maybe was introduced to complement -. I have no idea why ~ was introduced as a prefix operator. If we need ~ why don’t we need % or ~% or any other special character combo? I don’t have any special use cases for more prefix symbols, but I just want the language to be more consistent.


#8

I think the story basically is that since existing languages like Java
support those 4, they wanted scala to support them to, but like everything
in scala, it can’t be “special-cased” so they made it a general-purpose
mechanism. I assume that’s what Odersky meant by a “necessary evil.”

A lot of features in scala follow this thought process. For example, Java
has implicit conversions – between certain predetermined things. Scala
opens that up to be programmable. Java has type inference — in very
limited ways (e.g.,
http://james-iry.blogspot.com/2009/04/java-has-type-inference-and-refinement.html).
Scala opens it up to be general. Java has try catch. Scala unifies the
catch block with partial functions / pattern matching. (In fact, in scala
the “argument” to catch doesn’t have to be a partial function literal –
you can just refer to a named partial function!) And so on and so forth.

In the beginning of Programming in Scala they discuss this design
philosophy, using the analogy of the cathedral vs. the bazaar.


#9

~ is bitwise negation.


#10

This wasn’t possible until 2.12 (the Scala version, not the short month of 2012):

scala> val - = 42
-: Int = 42

scala> val i = -
i: Int = 42

The “Signs of Trouble” puzzler warns, “Don’t take everything you read literally.”

Not exactly relevant, but “Unary Quandary” is a pretty good puzzler title.

Whatever happened to the puzzling guy, and why isn’t there a puzzler forum?