Install the Scala IDE from the Scala IDE website.
There are two ways of executing your Scala code in the Scala IDE. You can play around with snippets of Scala code in a worksheet, or you can create a normal Scala file and execute it as an application.
To create a worksheet, right click your package in the Project Explorer and choose New > Scala Worksheet. Any Scala code you write will be executed, and the results printed to the side:
package edu.govschool.scala
object Demo {
def abs(x: Double) = if (x < 0) -x else x //> abs: (x: Double)Double
def sqrt(x: Double) = {
def sqrtIter(guess: Double): Double = {
if (isGoodEnough(guess)) guess
else sqrtIter(improve(guess))
}
def isGoodEnough(guess: Double): Boolean =
abs(guess * guess - x) / x < 0.001
def improve(guess: Double): Double =
(guess + x / guess) / 2
sqrtIter(1.0)
} //> sqrt: (x: Double)Double
sqrt(2) //> res0: Double = 1.4142156862745097
sqrt(4) //> res1: Double = 2.000609756097561
sqrt(1e-6) //> res2: Double = 0.0010000001533016628
sqrt(1e60) //> res3: Double = 1.0000788456669446E30
}
Otherwise, choose New > New Scala File, and give it a good name. Next, you'll need to add a bit of code to give yourself somewhere to have a main()
function:
package edu.govschool.scala
/**
* @author Mr. Davis
*/
class TestFile {
}
object Main {
def main(args: Array[String]) {
// Your code here
}
}
Now, you can write any Scala code you'd like, and just use that main function to start your program. If you just need a Scala class, you can choose that option as well, and not create a Main
object.
Everything (well, most everything) that we will do in Scala can be represented as mathematical/algebraic values and expressions that evaluate to those values. This method of computation was formalized into the λ-calculus in the early 20th century, and then introduced into the programming world by John Backus in his Turing Award lecture Can Programming Be Liberated from the Von Neumann Style? A Functional Style and Its Algebra of Programs [Stanford link].
So, we will only be working with two types of Thing™ in Scala:
Expressions: Computations on values, like
sumOfSquares(4, 5) or
{
(1 to 4).map {
i => "Happy Birthday " + (if (i == 3) "dear NAME" else "to You")
}.foreach { println }
}
Scala values are represented by literals, just like Java. Here are a few examples, and their types according to the Scala worksheet:
// Int literal
val i = 2 //> i : Int = 2
// Double literal
val d = 4.0 //> d : Double = 4.0
// Char literal
val c = 'd' //> c : Char = d
// String literal
val s = "Hello, Scala!" //> s : String = Hello, Scala!
// Boolean literal
val b = false //> b : Boolean = false
// Function literal with type Int => Int
val f = (x: Int) => x * x //> f : Int => Int = <function1>
Most of these are familiar to you from Java, but the new one is the last one, the function literal. In Scala, now functions are first-class values (FCV), just like numbers, classes, and booleans, among other things. Therefore, you can define a function anywhere you can define any other FCV. The function defined above could be called later by f(2)
or f(4)
, getting the square of the argument. However, for the time being these function literals are not very useful to us, and we will be defining functions in a slightly different way later.
An important thing to realize is that we are NOT assigning values to a variable, like in Java. We are binding a value to a name, hence the keyword val
. In most respects, these two operations are identical, however, Scala values are immutable. Just like in algebra, if I make binding x = 5
, I can't later in the problem redefine x, so in Scala this is illegal:
val x = 5
x = 6 // Error!
Immutable values prevent errors that occur due to variables being changed. This may seem like a restriction rather than an asset, but a majority of the errors in Java occur due to mutable variables.
As soon as we bind a value to a name, any necessary evaluation is done immediately and the value bound. So, in the case of val x = 2 + 2
, the expression 2 + 2
is immediately evaluated (to 4
, in case you were wondering), and that value bound to name x
. This makes sense most of the time when we are assigning the value of an expression to a name, but it doesn't sound like it will work for function literals, since they need to be evaluated every time they are called.
Therefore, to write functions, while it is legal to use val
(and sometimes we will, but rarely), we will mostly use def
, like below:
// (Int, Int) => Int
def sum(a: Int, b: Int): Int = a + b
// () => Unit
def printBirthdaySong = {
(1 to 4).map {
i => "Happy Birthday " + (if (i == 3) "dear NAME" else "to You")
}.foreach { println }
}
Just like function literals, normal functions have a type, which I have annotated above each function. Each argument must be typed, but the return type of the function can be left off. If there are no arguments, then even the parentheses can be left off!
Generally, you should leave off the return type of a function, since it can be inferred by the Scala compiler. There are three times, however, you should explicitly add the return type:
Functions are not the only type of useful expressions in Scala. We also have if-expressions and blocks.
If-expressions are like if-statements in Java, expect that they return a value. Here is a simple example:
val x = 5
val y = if (x < 10) {
"x is tiny!"
} else {
"x is big!"
}
If (no pun intended) the boolean expression (called a predicate) is true
, then the result of the first block is return, otherwise the result of the second block is return. This is the same as the ?:
operator in Java. But what exactly is a block? In Scala, a block is a group of expressions grouped with {}
, curly braces.
{
2 + 2
if (true) "hi" else "bye"
false
}
The example block above will return the boolean value false
, as that is the last value in the block. If the last thing in a block is an expression, then that expression is evaluated an returned. Because of this property, we do not need the return
keyword in functions, as the last expression/value in the function will automatically be returned!