Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Scala have a small number of underlying syntactic features?

Tags:

scala

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?

like image 489
erac Avatar asked Nov 10 '12 11:11

erac


2 Answers

There are two ways to understand your question about operators:

  1. What are the rules that govern how operators are treated by the Scala compiler? (Language Rules)
  2. What are the rules that govern how operators are defined in libraries? (Operator Definitions)

Language Rules

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.

Operator Definitions

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 or c :: d)
like image 119
Philippe Avatar answered Oct 12 '22 01:10

Philippe


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

like image 40
pagoda_5b Avatar answered Oct 12 '22 03:10

pagoda_5b