Why is Scala limited to just 4 prefix symbols?

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?

1 Like

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

1 Like

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.

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.)

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

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 ¯\_(ツ)_/¯ )

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.

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.

1 Like

~ is bitwise negation.

1 Like

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?