Luet oppimateriaalin englanninkielistä versiota. Mainitsit kuitenkin taustakyselyssä osaavasi suomea. Siksi suosittelemme, että käytät suomenkielistä versiota, joka on testatumpi ja hieman laajempi ja muutenkin mukava.
Suomenkielinen materiaali kyllä esittelee englanninkielisetkin termit.
Kieli vaihtuu A+:n sivujen yläreunan painikkeesta. Tai tästä: Vaihda suomeksi.
Chapter 1.4: Storing Values in Variables

Introduction: Intermediate Results
What arithmetic expressions would you write to compute the following three things?
the cube (third power) of the number six — that is, 63
the factorial of the number six — that is, 6!
the cube of the factorial of six — that is, 6!3
One answer is in the REPL interaction below.
6 * 6 * 6res0: Int = 216 1 * 2 * 3 * 4 * 5 * 6res1: Int = 720
That’s two down, no problem. But what about the third, the cube of the factorial?
Argh:
1 * 2 * 3 * 4 * 5 * 6 * 1 * 2 * 3 * 4 * 5 * 6 * 1 * 2 * 3 * 4 * 5 * 6res2: Int = 373248000
That’s pretty unpleasant to write and pretty unpleasant to read. What’s more, the computer performs more multiplications than necessary as it executes that command. (Although that doesn’t really matter in practice in this little program.)
It would be nice if we could write this: “Compute the factorial, store that intermediate result, then cube it.” And we can.
Variables
Pretty much all programs store values in the computer’s memory. By storing values, the computer can keep track of important informations while the program runs, such as intermediate results or, say, the ratings and prices that a user has entered in the GoodStuff app.
Once something is stored, we need to be able to access it. We can do that by defining a name that refers to the stored information.
To store values, programmers use variables (muuttuja). A variable is a named location where you can store a single value. Commanding the computer to store a value in a variable is called assignment (sijoitus):
Assigning an intermediate result to a variable
Here is a better way to compute “cube of factorial of six”.
To begin, let’s define a variable and store the intermediate result in it. Here’s how. Again, recall that you can hover your mouse cursor over the green boxes to see what each explanations refers to.
val factorial = 1 * 2 * 3 * 4 * 5 * 6
... a name that we chose, such as factorial
. The
name is in turn followed by an equals sign and...
... an expression that is evaluated to produce the value that gets stored in the variable.
The REPL responds:
val factorial = 1 * 2 * 3 * 4 * 5 * 6factorial: Int = 720
The REPL acknowledges the successful variable definition by
showing the name you chose (rather than the usual resX
)
and...
... the variable’s data type and the value stored in the variable. In Scala, both variables and values have data types, and the data type of a variable must be compatible with the value it stores.
Now we can use the variable to compute the cube:
factorial * factorial * factorialres3: Int = 373248000
Notice that a variable’s name alone is an expression. The expression’s value is the value that’s stored in the variable. A variable name, like any other expression, can appear as part of a more complex expression. In our example, the variable name appears (three times) as a subexpression of an arithmetic expression.
Stages of assignment
The animation below show how the computer runs the code that we just discussed. Please watch the animation even if you feel you understood the example already! Pay close attention to the order in which the steps are executed. The order of these steps during a program run will be increasingly important as we encounter increasingly complex programs.
Code ≠ the math you know
Some parts of program code look like familiar mathematical notation. That similarity has tripped up many beginner programmers, because programs and school math don’t work quite the same way.
Consider the assignment command. It’s not an equation. The two sides of the equals sign are not interchangeable. Instead, an assignment command tells the computer to evaluate the expression on the right and store the resulting value in the memory location named on the left.
We Just Improved Code Quality
Here are the two programs that we just wrote:
1 * 2 * 3 * 4 * 5 * 6 * 1 * 2 * 3 * 4 * 5 * 6 * 1 * 2 * 3 * 4 * 5 * 6res4: Int = 373248000
val factorial = 1 * 2 * 3 * 4 * 5 * 6 factorial * factorial * factorialres5: Int = 373248000
The second version solves the same problem as the original one-liner but is easier for a human to read. Another improvement (in principle) is that the computer has a bit less work to do. So we’ve just had our first brush with two criteria of program quality: programming style and efficiency of execution.
At least in principle, we can spot a third improvement in code quality, too. Because we extracted the factorial into a separate command, our code is now less repetitive. Less repetition means that the program is easier to develop and modify: if you wanted to, say, tweak the program to cube the factorial of eight rather than six, you’d find it easier to do that one the second version easier to work with, since you’d need to change the code in only one place rather than three. Not only does it less work for you, it also reduces the risk of careless mistakes.
Of course, in such a tiny example, all these quality improvements have little practical significance.
The principle of avoiding repetition goes by the acronym DRY (don’t repeat yourself); some people refer to breaches of this principle as WETWET (write everything twice write everything twice). When we write larger programs, it’s essential to keep our code DRY. At this introductory stage, however, it’s enough to sow a seed of thought: a programmer needs to consider not only whether a piece of code works but also whether it is of high quality.
Variable Names as Expressions and in Expressions
Variables of Various Types
So far, all our variables were of type Int
and stored integer values. We can define variables
of other types, too. The easiest way is to assign a value of a different type, like a Double
:
val courseGrade = 9.5courseGrade: Double = 9.5
Or a String
:
val name = "Anna"name: String = Anna val songIntro = "cccedddfeeddc---"songIntro: String = cccedddfeeddc---
Or a Color
or a Pic
, as in the following exercise.
How to Name a Variable
The programmer picks names — also known as identifiers (tunnus) — for the variables in their program. As you’ve probably noticed, variables in Scala are usually given names that begin with a lower-case letter. There’s no technical reason we have to do so, but it’s good style to follow this convention.

If a variable name comprises multiple words, we use upper-case letters to mark the word boundaries. Here are a few examples:
myLittleVariable
numberOfPlayers
xCoordinate
This naming convention is called “camelCase”. It’s the standard in Scala in many other languages, although alternative conventions also exist.
Don’t use spaces in variable names. Numbers are fine, but a name can’t begin with a
number. It’s best for beginners to avoid special characters such as +
or &
entirely;
some of these characters have specific meanings in Scala. Letters with diacritics
(e.g., á or ü) are technically okay, but since they cause occasional trouble in some
programming environments, it’s usually better to steer clear of them.
Scala’s “magic words”, such as val
— which are properly termed reserved words
(varattu sana) — can’t be used as names.
Characters in upper case are distinct from those in lower case, so if you name your
variable myTest
, be sure to type it the same way every time. The name mytest
won’t
work for accessing the variable.
It’s a good practice to give variables names that describe their purpose. You will see
many examples of that in this ebook. However, when you’re just experimenting on a tiny
piece of code, it’s fine to use short, generic names like number
, a
, or myTest
,
even if the name doesn’t clearly show what the variable is for.
O1’s style guide has a bit more to say about naming. We recommend checking it out at some point during the first weeks of O1, but it’s not necessary to do that just yet.
Variables and Strings
Embedding values in a string
Let’s use this integer variable:
val age = 20age: Int = 20
Suppose we want to produce a sentence that describes the information stored in that variable. For instance, we might want the sentence to look like this: “The customer is X years old.”, with X replaced by the value stored in the variable. (This is a common sort of thing to do. Countless application programs generate text based on data stored in memory.)
Here’s one way to do it:
s"The customer is $age years old."res6: String = The customer is 20 years old.
Notice the letter s
just before the opening quotation mark.
It signals that we’re embedding values within a string literal.
This is known as string interpolation.
Inside the string literal, we include a variable name preceded
by a dollar sign. It will be replaced by the variable’s value.
This works as long as you don’t forget the s
at the beginning.
(What happens if you do forget? Take a guess and try it in the
REPL to see if you were right.)
The value is of type String
and contains the number’s digits
as written characters, not as numerical values.
Let’s look at some additional examples of string interpolation.
val number = 10number: Int = 10 s"The number twice with spaces in the middle: $number $number"res7: String = The number twice with spaces in the middle: 10 10
You can embed multiple expressions in a single string. The code above embeds the same expression twice; the code below embeds two different expressions.
s"$number is slightly less than ${number + 1}."res8: String = 10 is slightly less than 11.
You can also embed a more complex expression than a variable name. This calls for curly brackets that separate the expression from the rest of the string, as shown for the arithmetic expression just above. (What happens if you forget the curly brackets? Take a guess, then try it in the REPL to see if you were right.)
The same works for data types other than Int
as well. Double
s,
for instance:
val grade = 9.5grade: Double = 9.5 val report = s"grade: $grade"report: String = grade: 9.5 s"$grade is the grade you got"res9: String = 9.5 is the grade you got
And you can embed strings within a longer string:
val name = "Anna"name: String = Anna println(s"$name, $report")Anna, grade: 9.5
That last command does the same as this next one, which uses the familiar plus operator to put strings together:
println(name + ", " + report)Anna, grade: 9.5
The plus operator on String
s
You’ve seen how to use the plus operator to create combinations of strings. You can also use the plus to combine a string with a value of a different type. The result is the same as with string interpolation:
"The customer is " + age + " years old."res10: String = The customer is 20 years old. "The number twice with spaces in the middle: " + number + " " + numberres11: String = The number twice with spaces in the middle: 10 10 val report = "grade:" + gradereport: String = grade: 9.5
In real-world Scala programs, both the plus operator and string interpolation
(s
-and-dollar) are used. You should know both notations, and we will be using both
in this ebook too.
However, the plus operator has one limitation that you should know about. Compare these two expressions:
s"$grade is the grade you got"res12: String = 9.5 is the grade you got grade + " is the grade you got"-- Deprecation Warning: |grade + " is the grade you got" |^^^^^^^ |... Adding a number and a String is deprecated. Use the string interpolation `s"$num$str"`
The first command uses string interpolation and works fine. One might well assume the second command to work equally well. But instead, the second command produces a warning message: the Scala toolkit warns us not to do that.
The plus operation that combines a string with a number works like this: “combine the string on the left of the plus sign with the number on the right”. The other way around — with the number on the left — is not okay.
Don’t use the plus operator when you have a number on the left like that. Use string interpolation instead, as the warning message suggests.
Alternative approaches
(This is not important right now but may interest some readers. Don’t feel bad about skipping this bit.)
There are still other ways of constructing strings. For example, all the following expressions evaluate to the same result:
s"$grade is the grade you got"res13: String = 9.5 is the grade you got "" + grade + " is the grade you got"res14: String = 9.5 is the grade you got grade.toString + " is the grade you got"res15: String = 9.5 is the grade you got
""
stands for the empty string (tyhjä
merkkijono) that contains zero characters but
is nevertheless a string. If you combine the
empty string with a number, you get that number’s
digits in a string (which you can further combine
with other values). We’ll use the empty string
more in Chapter 4.1.
Music at Different Speeds
Think back to the play
command that was introduced in Chapter 1.3 and the song Ukko
Nooa (“Uncle Noah”). Let’s use variables to form a slightly longer string that covers
the entire song. In Ukko Nooa, the melody at the beginning repeats at the end. That’s
easy to achieve:
val beginning = "cccedddfeeddc---"beginning: String = cccedddfeeddc--- val middlePart = "eeeeg-f-ddddf-e-"middlePart: String = eeeeg-f-ddddf-e- val wholeSong = beginning + middlePart + beginningwholeSong: String = cccedddfeeddc---eeeeg-f-ddddf-e-cccedddfeeddc--- play(wholeSong)
Now let’s see how we can play this song at two different tempos (speeds). Let’s begin by storing the tempos in variables with descriptive names:
val normalTempo = 120normalTempo: Int = 120 val slowTempo = 60slowTempo: Int = 60
The play
command can play melodies at different speeds. If you want
something other than the default tempo, you need to give play
a string
that contains the melody, followed by a slash, followed by the tempo. Such
as this one:
wholeSong + "/" + normalTempores16: String = cccedddfeeddc---eeeeg-f-ddddf-e-cccedddfeeddc---/120
Here are a couple more examples for you to try:
play(wholeSong + "/" + normalTempo)play(wholeSong + "/" + slowTempo)
It just so happens that 120 is the default tempo used by play
,
so the first command produces the exact same sounds as before.
A tempo of 60 plays at a more leisurely pace, as befits Uncle Noah’s advanced age.
You’re not obliged to use variables for this. You can just write the desired tempo directly into a string literal, as below.
play("cdefg/140")
Changing the Value of a Variable
Programs often track information that changes over time. For instance, a game might have a character whose coordinates change as the player moves the character, or the favorite hotel of a GoodStuff user might change as the user records new experiences.
One way to handle this is to store the changing information in a variable and replace the value of the variable with another as needed.
That sounds pretty good. But it turns out we can’t do that using variables defined with
the val
keyword. The value of a val
variable is “locked” into the variable and can’t
be replaced with another.
var
variables
In Scala, you can use the word var
instead of val
when creating a variable. A var
variable is assigned a value just like a val
variable is. The only difference —
but a very important one — is that a var
lets us replace the stored value with a
new one later on.
Take a close look at the following animation.
In this example, the values of both variables number
and doubleThat
were eventually
replaced with new ones. This was possible because we defined them with var
. If you were
to exchange those var
s for val
s, the above code wouldn’t work; you’d get the error
message “error: reassignment to val”.
A potentially confusing feature of the REPL
The REPL lets you define a variable with the same name as another
you had previously defined: just write a new var
or val
definition. If you do this, you might get the impression that you
can change the value of a val
variable. But in reality, what
you’re doing is discarding the old variable and making an entirely
new one in its stead (perhaps even with a different data type).
This is a feature specific to the REPL. In Scala programs outside the REPL, you cannot enter consecutive commands to create namesake variables like this. So forget about this, at least until you’re fluent with variables.
Another example
When you replace the value of a var
, you can make use of the variable’s old value as
you specify the new one:
Watch out for math! (again)
Note and remember: In mathematics, a variable is a symbol that corresponds to a value. In programming (of the sort that we do here), a variable is a named location in memory capable of storing a single value.
This difference is particularly significant when you’re using
var
variables. A program is not a group of equations! The same
program can very well contain, for example, number = 10
and
number = 5
. Even number = number + 10
is valid, even though
it is suspicious if you look at it through the familiar lens of
math.
And if you have a sequence of commands that assigns values to variables, the order of those commands can make a big difference!
Why val
?
Objection! Why would I ever use val
? Doesn’t var
let me do all the same stuff and
more?
It’s true that var
variables present certain additional opportunities, but that isn’t
necessarily a good thing.
As programmers write code and try to locate errors in it, they constantly reason about
how their code works. It’s much easier to reason about code when you know that certain
things in the program cannot change. As a simple example of this, the word val
tells
the programmer that the variable’s value will never, ever change no matter what else
happens during the program run. This will become even more important as your programs
grow larger and more complex; no doubt you’ll notice the benefits of val
s already
during this introductory course.
In small REPL experiments, it doesn’t much matter which kind of variable you use, but here’s a rule of thumb for all future programming tasks outside the REPL:
Make every variable a
val
, unless you have a good reason right now to make it avar
.
Don’t use var
s “just in case I need to change the value”. That is poor practice.
If it turns out later that a val
really doesn’t fit what you’re trying to do, you
can modify your program to use a var
instead.
How is a val
even a “variable”?
You might think that, in a sense, only var
s are proper variables,
since their values can vary. However, there are good reasons to call
val
s variables, too.
For one thing, a val
can receive different values during different
program runs (e.g., from user input). For another, it’s possible for
the same val
definition to be executed multiple times during a
program run, so that each execution creates a separate val
with
a different value. You’ll see examples of both things later on.
The mathematical concept of variable is actually closer to val
s
than to var
s. In fact, it’s been suggested by some that it’s only
val
s that deserve to be valled, whereas var
s would be better
called “assignables” or something like that. But we’ll leave that
war of words be.
Functional programming
Functional programming (funktionaalinen ohjelmointi) is
one of the major varieties, or paradigms, of
programming. In its purest form, functional programming uses only
val
s — no mutable variables at all. We’ll discuss that in
Chapter 11.2.
Student question: In terms of memory use or efficiency, does it make a difference if I pick val
or var
?
Taken in isolation, there’s no difference between the two in this respect. The amount of memory reserved for a variable depends only on the variable’s data type; we’ll discuss that in Chapter 5.4.
In practice, though, the matter is more complicated. For one thing,
the choice between var
and val
affects the optimizations that
compilers apply as they translate Scala code into a more readily
executable form.
Moreover, val
s help us write programs that can be run efficiently
in parallel by multiple computers or processor cores. However,
parallel execution is not a theme that we’ll be exploring in O1.
More var
s and stringed instruments
play
and MIDI sound synthesis
The play
command supports instruments that are defined in the
General MIDI standard, where MIDI is short for Musical Instrument
Digital Interface. It synthesizes sound on a variety of virtual
instruments; the quality of the output varies greatly. O1’s play
command is an easy-to-use, string-based interface to some of the
basic MIDI features.
You can find a numbered list of MIDI instruments on the midi.org website.
In O1, we use MIDI sound for learning programming, not for serious audio quality. We use strings to represent notes, not actual recorded sound. The digital representation of sound and recorded audio are some of the topics in Programming Studio 1.
play
and dots
In the melody we just played, some of the notes were followed by
period-dots. The play
command interprets each note followed by
a dot as a staccato: a shorter, crisp note followed by a short
pause.
var
and data types
The data type of a variable determines which values you can store in it. A variable’s
type never changes, not even if the variable is a var
. For instance, if you have a
variable of type String
, you can assign only strings to it, as shown below.
var title = "Ms."title: String = Ms. title = "M.Sc."title: String = M.Sc. title = 12345-- Error: |title = 12345 | ^^^^^ | Found: (12345 : Int) | Required: String
Interpreting error messages is a skill that you’ll develop as you gain experience. The above message means roughly this:
“I found 12345 here on the right of the equals sign; that’s an integer. But I was expecting a
String
, because you’re assigning to aString
variable.”
Combining numerical types
Sometimes it might seem like we can break the rule of type compatibility. One such
case arises when we assign an Int
value to a variable of type Double
, as at the
end of this interaction:
var someNumber = 123.45someNumber: Double = 123.45 val evenFigure = 100evenFigure: Int = 100 evenFigure * evenFigureres17: Int = 10000 someNumber = evenFiguresomeNumber: Double = 100.0 someNumber * evenFigureres18: Double = 10000.0
That last assignment command is valid: the Int
value that we got from evenFigure
“serves as a Double
”.
But as you can tell from the last few lines, it’s not
the Int
from the variable that gets stored in someNumber
;
what gets stored is the corresponding Double
value. Using
that Double
in arithmetic yields more Double
s.
This interplay between Int
s and Double
s is convenient. It lets us write
components that should work on Double
s but that should also work similarly
on integers. Which is quite common.
res
Variables in the REPL
You’ll be familiar already with how the REPL replies with a val res
prefix when you feed
it an expression. In fact, what the REPL does here is create new val
variables whose
names begin with res
. You can use these variables just like any other variables that
you define explicitly:
1 + 1val res19: Int = 2 res19 * 10val res20: Int = 20 val total = res19 + res20val total: Int = 22
This ebook’s REPL examples usually don’t show these ubiquitous
val
s in the output, but you see them in IntelliJ. Each of these
three val
s is there to say that a variable got defined; the
first two have been automatically named by the REPL.
You can take advantage of this as you experiment in the REPL. However, in this ebook, we
don’t use these res
-prefixed variables, however. One of the reasons is that we wish to
focus on programming techniques that work outside of the REPL, too. The numbered res
variables are peculiar to the REPL environment.
Summary of Key Points
A variable is a named storage location for a single value. You use variables to store information in the computer’s memory.
For instance, in the GoodStuff program, variables store information about each experience (price, rating) and the user’s favorite experience.
You can access the value stored in a variable through the variable’s name. A variable name is an expression and can also appear as a part of a compound expression.
Scala has two kinds of variables:
val
andvar
.A
val
gets assigned a value and continues to store that value thereafter. Favoringval
s makes programs easier to read and develop. You should primarily useval
s.A
var
can be assigned a new value, which replaces the old one.var
s enable direct mutations to program state with assignment commands. You should use them sparingly, only when needed.
Meaningful variables names improve readability. Variables may also affect a program’s efficiency and ease of modification.
Links to the glossary: variable, assign; expression, value, to evaluate;
var
variable,val
variable; reserved word; DRY; string interpolation.
Finally, here’s the concept map from the previous chapter, expanded with a few key concepts from this one.
Feedback
Please note that this section must be completed individually. Even if you worked on this chapter with a pair, each of you should submit the form separately.
Credits
Thousands of students have given feedback and so contributed to this ebook’s design. Thank you!
The ebook’s chapters, programming assignments, and weekly bulletins have been written in Finnish and translated into English by Juha Sorva.
The appendices (glossary, Scala reference, FAQ, etc.) are by Juha Sorva unless otherwise specified on the page.
The automatic assessment of the assignments has been developed by: (in alphabetical order) Riku Autio, Kai Bukharenko, Nikolas Drosdek, Kaisa Ek, Rasmus Fyhrqvist, Joonatan Honkamaa, Antti Immonen, Jaakko Kantojärvi, Onni Komulainen, Niklas Kröger, Kalle Laitinen, Teemu Lehtinen, Mikael Lenander, Ilona Ma, Jaakko Nakaza, Strasdosky Otewa, Kaappo Raivio, Timi Seppälä, Teemu Sirkiä, Onni Tammi, Joel Toppinen, Anna Valldeoriola Cardó, and Aleksi Vartiainen.
The illustrations at the top of each chapter, and the similar drawings elsewhere in the ebook, are the work of Christina Lassheikki.
The animations that detail the execution Scala programs have been designed by Juha Sorva and Teemu Sirkiä. Teemu Sirkiä and Riku Autio did the technical implementation, relying on Teemu’s Jsvee and Kelmu toolkits.
The other diagrams and interactive presentations in the ebook are by Juha Sorva.
The O1Library software has been developed by Aleksi Lukkarinen, Juha Sorva, and Jaakko Nakaza. Several of its key components are built upon Aleksi’s SMCL library.
The pedagogy of using O1Library for simple graphical programming (such as Pic
) is
inspired by the textbooks How to Design Programs by Flatt, Felleisen, Findler, and
Krishnamurthi and Picturing Programs by Stephen Bloch.
The course platform A+ was originally created at Aalto’s LeTech research group as a student project. The open-source project is now shepherded by the Computer Science department’s edu-tech team and hosted by the department’s IT services; dozens of Aalto students and others have also contributed.
The A+ Courses plugin, which supports A+ and O1 in IntelliJ IDEA, is another open-source project. It has been designed and implemented by various students in collaboration with O1’s teachers.
For O1’s current teaching staff, please see Chapter 1.1.
Additional credits for this page
This chapter does injustice to music by Edvard Grieg. Thank you and sorry.
We use the Scala keyword
val
(short for “value” or “value variable”). We follow it with...