Frequently asked questions, with brief answers and/or links to longer answers.
This list only includes questions that actually come up over and over again in Scala chat rooms and forums.
Where can I ask Scala questions?
See our Community page.
What’s a good book about Scala?
Our Books page lists a few especially popular, well-known books.
We don’t have a list of all the Scala books that are out there; there are many.
You can go on the #scala-users room on Discord or another community forum and ask for book recommendations. You’ll get more helpful answers if you provide some information about your background and your reasons for wanting to learn Scala.
Should I learn Scala 2, or Scala 3?
Don’t sweat the decision too much. You can’t go far wrong either way. It isn’t that hard to switch later, in either direction.
Scala 2 remains a common and reasonable choice. Most Scala jobs are still Scala 2 jobs. Scala 2 also has a somewhat bigger library ecosystem, somewhat better tooling support, and somewhat wider availability of learning materials.
That said, these gaps are getting narrower every month. Plenty of books are available, a rich library ecosystem already exists, and there are more and more jobs using Scala 3. You should strongly consider learning Scala 3. It’s still fairly new, released in 2021. But it’s the future, and it’s the best version for falling in love with the language and everything it has to offer.
Where are Scala jobs advertised?
This is addressed on our Community page.
In short, the only officially sanctioned place is the #jobs channel on Discord.
Who’s behind Scala?
This is answered on the community page.
Can I use the Scala logo?
What compiler flags are recommended?
The list of available options is here.
What flags people choose varies widely from shop to shop and from
individual to individual.
-Xlint is valuable to enable. Some brave
-Xfatal-warnings) to make warnings
sbt-tpolecat is an opinionated sbt plugin that sets many options automatically, depending on Scala version; you can see here what it sets. Some choices it makes are oriented towards pure-functional programmers.
How do I find what some symbol means or does?
A Stack Overflow answer lays out what the different kinds of symbol in Scala are and explains the most commonly used symbols.
Scala allows symbolic method names. So if you see a random-looking
>=@=> in Scala code, it might simply be a method in
some library, rather than having any special meaning in the language
You can search for symbols on Google. For example, if you want to
<:< means, searching for
scala <:< works fine. If you
get poor results, try surrounding the symbol with double quotes.
I want Scala 2.13 (or some other version); why does sbt say it’s using Scala 2.12?
sbt 1.x always uses Scala 2.12 to compile build definitions. Your sbt 1.x build definition is always a Scala 2.12 program.
Regardless, in your
build.sbt, you can set
scalaVersion to whichever
available distribution you want and your program code will be compiled with that version.
I want Scala 3. Why does
versionNumberString say I’m on 2.13?
To aid migration, Scala 3 currently uses the Scala 2.13 library as-is,
with only minor supplements. That’s why
versionNumberString report that Scala 2 is in use:
Welcome to Scala 3.3.1 (17.0.3, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help. scala> util.Properties.versionNumberString val res0: String = 2.13.10
Note that even the latest Scala 3 version might not use the very latest Scala 2 standard library, since the 3 and 2 release schedules aren’t coordinated.
So how do you ask for the Scala 3 version number? Scala 3 offers
dotty.tools.dotc.config.Properties.versionNumberString, but only if
you have scala3-compiler on the classpath. So that works in the Scala 3
REPL, but won’t work in typical Scala 3 application code.
For an alternative way to detect the Scala 3 version, see this gist.
Why is my (abstract or overridden)
Which type of collection should I choose?
See the Scala 2.13 Collections Guide.
What are context bounds?
It’s syntactic sugar for a context parameter (an
implicit parameter in Scala 2, or a
using parameter in Scala 3).
for / yield work?
It is syntactic sugar for nested
For an in-depth explanation see this Stack Overflow answer.
What is the difference between view, stream and iterator?
Many things really, depending on the context. This answer on Stack Overflow has a good summary of all the meanings it has.
Note that, even if the specific meaning is different, according to the situation, it usually means “anything”.
Why doesn’t my function literal with
_ in it work?
Not all function literals (aka lambdas) can be expressed with the
Every occurrence of
_ introduces a new variable. So
_ + _ means
(x, y) => x + y, not
x => x + x. The latter function cannot be
written using the
Also, the scope of
_ is always the smallest enclosing expression.
The scope is determined purely syntactically, during parsing, without
regard to types. So for example,
foo(_ + 1) always means
x + 1); it never means
x => foo(x + 1). The latter function cannot
be written using the
See also SLS 6.23.2.
Can I chain or nest implicit conversions?
Not really, but you can make it work.
However, note that implicit conversions are, in general, discouraged.
Where does Scala look for implicits?
See this answer on Stack Overflow.
Why do primitive type parameters erase to
So for example, a
List[Int] in Scala code will appear to Java as a
List[Object]. The Java type system doesn’t allow primitive types to
appear as type parameters, but couldn’t they appear as their boxed
equivalents, such as
One would hope so, but doing it that way was tried, and it proved impossible. This SO question sadly lacks a concise explanation, but it does link to past discussions.
What’s the difference between methods and functions?
For example, how does a method such as:
def square(x: Int): Int = x * x
differ from a function value such as:
val square: Int => Int = x => x * x
Nevertheless, it is still recommended to use methods most of the time, unless you absolutely need a function. And, thanks to eta-expansion you rarely would need to define a function rather than a method.
What’s the difference between types and classes?
Types are primarily a compile-time concept. At compile time, every expression is assigned a type by the compiler.
Classes are primarily a runtime concept and are platform-dependent. At runtime on the JVM, every value is either a primitive value or an instance of exactly one class.
Some type information exists only at compile time, for multiple reasons, most notoriously type erasure.
For an in-depth treatment of types vs. classes, see the blog post “There are more types than classes”.
How can a method in a superclass return a value of the “current” type?
First, note that using
this.type won’t work. People often try that,
this.type means “the singleton type of this instance”, a
different and too-specific meaning. Only
this itself has the
this.type; other instances do not.
What does work? Possible solutions include F-bounded polymorphism (familiar to Java programmers), type members, and the typeclass pattern.
It’s a “type constraint”, and it comes from the standard library, not from the language itself. See this blog post.
I dislike requiring callers to wrap optional arguments in
Some(...); is there a better way?
Not really. See this answer on Stack Overflow.
implicit val usually recommended over
The latter has a singleton type, which is too specific. See answer on Stack Overflow.
I got a
StackOverflowError while compiling my code. Is it a compiler bug?
It might be.
To find out, try giving the compiler more stack and see if the error goes away.
It’s possible for the compiler to run out of stack when compiling some kinds of heavily nested code. The JVM’s default stack size is rather small, so this can happen sooner than you might expect.
The stack size can be changed by passing
-Xss... at JVM startup, for
-Xss16M. How to do this depends on what IDE and/or build
tool you are using. For sbt, add it to
If the stack overflow doesn’t go away no matter how much stack you give the compiler, then it’s a compiler bug. Please report it on the Scala 2 bug tracker or Scala 3 bug tracker, but check first if it’s a duplicate of an existing ticket.
I set a setting in sbt but nothing happened. Why?
There could be a lot of reasons. An extremely common one, that almost everyone runs into sooner or later, is that you have a bare setting in a multi-project build.
For example, if you add this to your
scalaVersion := "2.13.12"
that’s a “bare” setting, and you might expect it to apply build-wide. But it doesn’t. It only applies to the root project.
In many cases one should instead write:
ThisBuild / scalaVersion := "2.13.12"
Other possibilities include:
- the common settings pattern, where you put shared settings
val, typically named
commonSettings, and then
.settings(commonSettings)in every project you want to apply to them to.
- in interactive usage only,
Here’s some further reading: