Scala is an interesting language which claims to be concise, scalable (by having many features specified in libraries rather than the compiler), and to support DSLs. In trying to achieve this it has lots of operators plus compiler tweaks (e.g. to support infix operators and for example : _* to flatten a sequence).
I find the many operators (2½ pages in the 'Programming in Scala' index) and compiler tweaks confusing. To be fair many of the operators are conventional arithmetic/boolean operators borrowed from C et al).
I've been told that underpinning this there are a few basic syntactic rules, I think that if I knew these it would reduce my cognitive load.
Are there a few rules (and if so what are they) or am I doomed to have learn the many 'operator' methods and implicits in the libraries?
There are two ways to understand your question about operators:
There are rules indeed. I will let you determine whether you think there are "few" of them or not. As most things Scala, you can find them in the Language Reference, Section 6.12.
The most important bits:
The only accepted prefix operators are +
, -
, !
and ~
.
Any method that takes no argument can be used as a postfix operator.
Any method that takes one argument can be used as an infix operator. The precedence of these operations however is subject to specific rules, presumably mostly so that arithmetic and other expressions are treated as one would expect. The precedence is determined by the first character of the operator/method name, and matches what you would expect from C or Java.
All infix operators are left-associative, except for the ones that end with :
. Typical examples include ::
and +:
.
So four rules, basically. I encourage you to read the spec for more insight.
The choice of operator definitions is up to the library designer(s). The Scala collection library, for instance, uses a relatively small and consistent set of operators (++
, --
, **
, +=
, -=
, ++=
, --=
, +:
, etc.). Parser combinators come with a more exotic set, and some libraries can be completely impenetrable at first to the profane because of their custom operator definitions (sbt or Lift come to mind, although this is just my personal opinion).
This has been recognized as a source of potential problems and the Scala style guide has this to say about symbolic method names (custom operators):
Avoid! Despite the degree to which Scala facilitates this area of API design, the definition of methods with symbolic names should not be undertaken lightly, particularly when the symbols itself are non-standard (for example,
>>#>>
). As a general rule, symbolic method names have two valid use-cases:
- Domain-specific languages (e.g.
actor1 ! Msg
)- Logically mathematical operations (e.g.
a + b
orc :: d
)
Scala have no special treatment for operators
Extracted from the book "Programming in Scala 2ed"
Any method can be an operator
In Scala operators are not special language syntax: any method can be an operator. What makes a method an operator is how you use it. When you write “s.indexOf('o')”, indexOf is not an operator. But when you write “ s indexOf 'o' ”, indexOf is an operator, because you’re using it in operator notation.
I can't find the 2 1/2 pages in the index that you're referring to.
Scala operators are consistently available as methods defined on some object. This is consistent also with the fact that any value is represented as an object in scala, differing from java special legacy treatment for primitive types.
The scala underlying implementation can make use of primitives for performance gains at the bytecode level, but this is transparent for the end user.
Operators
So the rule here is simple: every operator is in fact a method defined on some type. The operator infix notation is just a matter of readability, e.g.
val sum = 1 + 2
reads much better than
val sum = 1.+(2)
This notation is also the base to build dsl with a "natural feel". The testing library ScalaSpecs gives a clear demonstration of this.
Special compiler rules
There is a limited number of "compiler tweaks", as you said, that are available for the aforementioned purpose of allowing clearer and more understandable code.
A relevant summary of those "tweaks" can found here
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