Published 2013-12-21.
Last modified 2024-07-18.
Time to read: 9 minutes.
This lecture is a first look at some simple Scala programs and how to run them using the Scala REPL. Variable definitions, method definitions, Scala / Java interoperability, the runtime fidelity if the REPL, expressions, and pasting transcripts are discussed. An exercise is also provided.
REPL stands for: read, evaluate, print loop. In other words, a REPL is an interpreter. Python, Ruby and Scala all have REPLs.
The Scala REPL provides 95% fidelity of the Scala runtime environment.
There are some important differences, however, and I will point them out as we go along.
You can try out the Scala REPL by typing scala
at a shell prompt:
The Scala 2 REPL and the Scala 3 REPL work differently in many ways.
I set JAVA_OPTS
as described in the Illegal Reflective Access section of the
Installing Scala lecture.
You may need to do this as well to run the Scala REPL.
REPL Help Messages
$ scala Welcome to Scala 2.13.0 (OpenJDK 64-Bit Server VM, Java 11.0.3). Type in expressions for evaluation. Or try :help.
scala> :help All commands can be abbreviated, e.g., :he instead of :help. :edit <id>|<line> edit history :help [command] print this summary or command-specific help :history [num] show the history (optional num is commands to show) :h? <string> search the history :imports [name name ...] show import history, identifying sources of names :implicits [-v] show the implicits in scope :javap <path|class> disassemble a file or class name :line <id>|<line> place line(s) at the end of history :load <path> interpret lines in a file :paste [-raw] [path] enter paste mode or paste a file :power enable power user mode :quit exit the interpreter :replay [options] reset the repl and replay all previous commands :require <path> add a jar to the classpath :reset [options] reset the repl to its initial state, forgetting all session entries :save <path> save replayable session to a file :sh <command line> run a shell command (result is implicitly => List[String]) :settings <options> update compiler options, if possible; see reset :silent disable/enable automatic printing of results :type [-v] <expr> display the type of an expression without evaluating it :kind [-v] <expr> display the kind of expression’s type :warnings show the suppressed warnings from the most recent line which had any
Scala 3 removed most of the REPL commands:
$ scala $ Welcome to Scala 3.4.2 (11.0.23, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help.
scala> :help The REPL has several commands available:
:help print this summary :loadinterpret lines in a file :quit exit the interpreter :type evaluate the type of the given expression :doc print the documentation for the given expression :imports show import history :reset [options] reset the repl to its initial state, forgetting all session entries :settings update compiler options, if possible
Using the REPL
Let’s output the obligatory “Hello, world!” message:
scala> println("Hello, world!") Hello, world!
We can define an immutable variable called x
by using val
:
scala> val x = 3 x: Int = 3
After you typed the above Scala expression and pressed Enter, the Scala REPL displayed the name of the variable, followed by its type and then its value.
You can also explicitly define the type of the variable, if you are concerned that someone reading your code might be uncertain about the type that might be inferred:
scala> val x: Int = 3 x: Int = 3
If a variable’s type does not match the type of an assingment value, a compile-time error will occur. Scala 2 displays the error like this:
scala> val x: Int = "three" <console>:7: error: type mismatch; found : String("three") required: Int val x: Int = "three"
Scala 3 displays the error like this:
$ scala Welcome to Scala 3.4.2 (11.0.23, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help.
scala> val x: Int = "three" -- [E007] Type Mismatch Error: ------------------------------------------------- 1 |val x: Int = "three" | ^^^^^^^ | Found: ("three" : String) | Required: Int | | longer explanation available when compiling with `-explain` 1 error found
Scala 3 with -explain
displays the error like this:
$ scala -explain Welcome to Scala 3.4.2 (11.0.23, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help.
scala> val x: Int = "three" -- [E007] Type Mismatch Error: ------------------------------------------------- 1 |val x: Int = "three" | ^^^^^^^ | Found: ("three" : String) | Required: Int |----------------------------------------------------------------------------- | Explanation (enabled by `-explain`) |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | Tree: "three" | I tried to show that | ("three" : String) | conforms to | Int | but none of the attempts shown below succeeded: | | ==> ("three" : String) <: Int | ==> String <: Int = false | | The tests were made under the empty constraint ----------------------------------------------------------------------------- 1 error found
Notice that Int
is spelled with an upper case I
:
scala> val x: int = 3 <console>:7: error: not found: type int val x:int = 3
Mutable Variables
We can define a mutable variable using var
(instead of val
), then change its value:
scala> var y = 4 y: Int = 4
scala> y = 36 y: Int = 36
Of course, we cannot change the value of an immutable variable. Scala 2 displays the following error message:
scala> x = 4 <console>:8: error: reassignment to val x = 4 ^
Scala 3 displays the error like this:
scala> x = 4 -- [E052] Type Error: ---------------------------------------------------------- 1 |x = 4 |^^^^^ |Reassignment to val x | | longer explanation available when compiling with `-explain` 1 error found
Lets use the -explain
option for Scala 3:
$ scala -explain Welcome to Scala 3.4.2 (11.0.23, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help.
scala> val x: Int = 3 val x: Int = 3
scala> x = 4 -- [E052] Type Error: ---------------------------------------------------------- 1 |x = 4 |^^^^^ |Reassignment to val x |----------------------------------------------------------------------------- | Explanation (enabled by `-explain`) |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | You can not assign a new value to x as values can't be changed. | Keep in mind that every statement has a value, so you may e.g. use | val x = if (condition) 2 else 5 | In case you need a reassignable name, you can declare it as | variable | var x = ... ----------------------------------------------------------------------------- 1 error found
Methods
We can define a method and invoke it in the REPL.
The type of argument x
is defined to be Int
,
and the implementation of the method follows the equals sign.
scala> def timesTwo(x: Int) = 2 * x timesTwo: (x: Int)Int
scala> timesTwo(21) res6: Int = 42
The Scala compiler inferred the return type of the method definition above as Int
.
It is generally a good habit to declare variable types and the return type of methods,
unless it is really obvious to a person reading your code:
scala> def timesTwo(x: Int): Int = 2 * x timesTwo: (x: Int)Int
If we declare the return type as Double
then the result will be converted from an Int
to a Double
:
scala> def timesTwo(x: Int): Double = 2 * x timesTwo: (x: Int)Double
scala> timesTwo(21) res7: Double = 42.0
Method Syntaxes
Methods can be defined within objects, classes and traits. When you define a method at the REPL prompt, the new definition is added to an invisible wrapper class. This section describes the various ways of when defining Scala methods.
If you only defined the signature of a method, and have not yet written the implementation (also known as the body),
but you want the code to compile, just write ???
to act as a placeholder for the body of the method.
The following method accepts two parameters (a String
and an Int
), and returns a String
:
def doSomething(a: String, b: Int): String = ???
If the method has a side effect (in other words, if it alters the program state),
but does not return a computable value, write it with empty parentheses and return Unit
:
def performSideEffect(): Unit = ???
Compare the above with the syntax used for a method that returns no value and has no side-effects. Obviously, if a method has no side effect and returns no computable value then it does not perform any useful work, so you should never see this syntax in a properly-written program:
def suspectMethod: Unit = ???
If a method has no side-effects, does not accept parameters and simply returns a value, it is termed referentially transparent.
Write it this way, without parentheses and declare the type returned.
In this case, the method returns an instance of X
:
def doSomething: X = ???
It is possible to use Scala’s type inference to figure out what the return type is. In this example, the return type is not declared. I do not recommend you get in the habit of writing methods this way, because this allows an entire class of programming errors to creep into your code.
def doSomething() = ???
Scala / Java Interoperability
Java to Scala
Scala does not define a String
class;
instead, it uses java.lang.String
.
We can create a String
in Scala just the same as we would in Java:
scala> "hello " res8: String = "hello "
Scala’s Predef
implicitly enriches Java String
s as required, so String
s appear to have extra capabilities.
Some of these capabilities are defined in
scala.
and two classes in the
scala.
package:
WrappedString
and
StringOps
.
Here is an example of a Java String
used in a Scala program:
scala> "hello " * 3 res9: String = "hello hello hello "
Scala’s Predef
also implicitly converts Java int
s and Integer
s into Scala Int
s as required:
scala> val i = new java.lang.Integer(123) i: Integer = 123
scala> i * 3 res10: Int = 369
All of Java’s numeric types are implicitly converted to Scala equivalents as required.
The Parametric Types lecture of the Intermediate Scala
course has more detail.
We will need to cover a lot of material before the Predef
magic makes sense,
so that’s why the lecture on Predef
is not presented in this course.
Scala to Java
Scala’s Predef
implicitly converts Scala objects into their Java equivalents as required.
The Java method System.out.println()
only works with Java values and objects,
so I will use it to demonstrate.
I’ll pass in a Scala Int
, and it will automatically be converted to a Java int
.
scala> System.out.println(i) 123
95% Runtime Fidelity

One of the biggest differences between the Scala REPL and the Scala compiler is that the Scala compiler does not allow you to redefine the type of a variable or method once it is defined.
The Scala REPL actually creates a new runtime context each time you issue a statement. As you experiment with the Scala REPL, realize that definitions might behave differently than they would when compiling a real Scala program.
Here is another difference: variables and methods are always associated with an instance of a class
or an object
.
We’ll talk about object
s more a bit later, but for now just know that they are singleton instances of a class
.
You can define an object
like this:
object Blah { val x = 3 def timesTwo(i: Int) = 2 * i }
For the REPL, you can paste in all of the lines together, like this:
scala> object Blah { | val x = 3 | def timesTwo(i: Int) = 2 * i | } // defined object Blah
Notice that the REPL printed vertical bars between the opening and closing braces to indicate that the expression I typed continued from line to line. We could also use a semicolon to separate the statements if they are written on the same line, like this:
scala> object Blah { val x = 3; def timesTwo(i: Int) = 2 * i } // defined object Blah
Unknown to us, the Scala REPL wrapped the variables and methods we defined earlier in this lecture in an object
.
We don’t have access to the object
itself, just its properties and methods.
You do have access to the Blah
object we just created, however:
scala> Blah.x res8: Int = 3
scala> Blah.timesTwo(21) res9: Int = 42
Exercise 1
Define a method that squares any Int
passed to it, and test it on a variety of input values.

Solution 1
$ scala Welcome to Scala 2.13.14 (OpenJDK 64-Bit Server VM, Java 17.0.11). Type in expressions for evaluation. Or try :help.
scala> def square(i: Int) = i * i def square(i: Int): Int
scala> square(3) val res0: Int = 9
scala> square(-5) val res1: Int = 25
Everything is an Expression
An expression is a combination of values and functions that are combined and interpreted by the compiler to create a new value, as opposed to a statement which is just a standalone unit of execution and doesn’t return anything. One way to think of this is that the purpose of an expression is to create a value (with some possible side-effects), while the sole purpose of a statement is to have side effects. In Scala there are many more expressions than statements.
In Scala, expressions return a value, while statements return Unit
,
which is a marker that indicates no value is returned.
Another way of saying this is that everything in Scala is an expression;
statements are expressions that return Unit
.
A block of code is an expression, and the last expression in the block establishes the return value.
For example, here is a statement that computes the value of Pi/2
(90 degrees, expressed in radians):
scala> math.Pi / 2.0 res0: Double = 1.5707963267948966
The REPL stored the value returned by the computation in a new variable it created called res0
and displayed the value on the console.
We can store the result of the expression in a variable with a name of our choosing:
scala> val ninety = math.Pi / 2.0 ninety: Double = 1.5707963267948966
Here is a method definition that encapsulates the computation. This method is a bit unusual in that it does not accept any parameters, but that is valid. The computed value of the expression math.PI / 2.0
becomes the value returned by the method.
scala> def piBy2: Double = math.Pi / 2.0 piBy2: Double
When we call the piBy2
method the REPL stores the value returned by the method into a new variable called res1
and displays the value on the console:
scala> piBy2 res1: Double = 1.5707963267948966
Again, we can store the returned value in a variable name of our choosing:
scala> val zzpluralz = piBy2 zzpluralz: Double = 1.5707963267948966
Only the value of the last expression in a block of code is returned.
String Interpolation
We can insert a println
in a block of code.
This technique is often used for debugging.
def piBy2: Double = {
val result = math.Pi / 2.0
println(s"result=$result")
result
}
The above method has 3 lines:
- Declares an immutable variable called
result
and compute its value and type. - Computes an interpolated string value and output it.
-
The value returned by the block is the value of the last expression that was evaluated for that block,
which is the value of the
result
variable.
If we run the above by pasting the code into the Scala REPL, then typing the name of the method, we get the following:
scala> piBy2 result=1.5707963267948966 res3: Double = 1.5707963267948966
Note the expression s"result=$result"
This is called string interpolation, and it allows you to easily create String
s using variable values.
- Prepending
s
to any string literal allows the usage of variables directly in the string - Each variable reference is prefixed by a dollar sign ($).
-
You can enclose computations and chained method calls within curly braces following a dollar sign,
such as
s"result = ${ 1 + result }"
- Within curly braces, spaces are optional, and semicolons can be used to separate expressions
In addition to s
interpolation, there are other kinds of string interpolations,
including f
for formatting, and raw
for raw strings.
Even Scala’s if
-then
-else
construct is an expression.
The value returned from a Scala if
-then
-else
expression is commonly used to set a variable or as a method’s return value.
For example, let’s create two variables, x
and y
,
and return the larger of the two:
scala> val x = 13 x: Int = 13
scala> val y = 14 y: Int = 14
scala> if (x>y) x else y res4: Int = 14
Notice that the value of the else
clause became the value of the entire if
expression.
We can wrap this computation in a method called intMax
.
The following performs the same function as math.max
, except that intMax
is limited to working with Int
arguments:
scala> def intMax(x: Int, y: Int) = if (x>y) x else y intMax: (x: Int, y: Int)Int
scala> intMax(13, 14) res5: Int = 14
The compiler is smart enough to know that the value returned by bigger
must be an Int
,
but you can declare the return type if you wish to avoid bugs that tend to creep in when no-one is watching:
def intMax(x: Int, y: Int): Int = if (x>y) x else y
Pasting a Transcript
The REPL can accept a previously transcribed REPL session, parse out the original text entered by the user and replay the original text. This is handy when typing along with a ScalaCourses lecture.
All you have to do is select the original text of an SBT REPL session from a web page or other text source,
copy the entire text, including the scala>
prompts and REPL responses, move to the Scala REPL,
paste in the text and press Ctrl-D.
The original text will then be replayed, and new variables will be allocated.
The copy action varies depending on the OS and the program that you are copying from: usually Ctrl-C or Cmd-C will copy the currently selected text to the operating system’s paste buffer, but some programs use Ctrl-Shift-C or Ctrl-Ins and for other programs such as X-Windows and ConEmu, merely selecting text causes it to be copied to the paste buffer.
Let’s try this for the REPL session we just looked at. After copying the text shown above into the system paste buffer, paste it into the REPL window.
Again, the paste action varies depending on the program that you are pasting into: usually Ctrl-V or Cmd-V will paste the contents of the operating system’s paste buffer into the currently active window, but some programs use Shift-Ins and for other programs such as X-Windows and ConEmu, a right-click with the mouse performs the paste action.
Once you have pasted a copy of the transcript into the REPL, press Ctrl-D (shown as ^D).
scala> val x = 13
// Detected repl transcript paste: ctrl-D to finish.
x: Int = 13
scala> val y = 14 y: Int = 14
scala> if (x>y) x else y res13: Int = 14 ^D // Replaying 3 commands from transcript.
scala> val x = 13 x: Int = 13
scala> val y = 14 y: Int = 14
scala> if (x>y) x else y res0: Int = 14
The original REPL transcript created variables called x
and y
,
and the replayed transcript does the same.
Notice that the last line allocates a variable called res0
,
even though the original transcript’s allocated res13
.
This is because the current REPL session’s automatic variable assignments are independent of the original REPL
transcript’s automatic variable assignments, even when pasting in a transcript.
© Copyright 1994-2024 Michael Slinn. All rights reserved.
If you would like to request to use this copyright-protected work in any manner,
please send an email.
This website was made using Jekyll and Mike Slinn’s Jekyll Plugins.