A scala file contains a collection of declarations: variables, values (constants), functions, singleton objects, traits (like interfaces) and classes.
Here's a basic Scala program: basics.scala.
Our singleton declares functions, procedures, variables, and values:
var balance = 100.0
val c = 299792458 // speed of light in
meters/sec
def square(x: Double) = x * x
It's not necessary to declare the types of variables and values, Scala will figure it out from the initial value. But if you want to use an initial value of a different type, then you should declare the type. For example:
var balance: Double = 100 // 100 is an Int, not a Double
val c: Double = 299792458
def square(x: Double): Double = x * x
Variables can be updated using an assignment, but not values:
balance = balance + 20 // now balance contains $120
c = 186000 // error, values can't be changed
One or more functions can be declared as runnable functions by using the "@main" annotation:
@main def run(): Unit =
println("Hello World")
Scala allows users to declare singletons. A singleton is a
stand-alone object:
object basics {
// methods and fields go here
}
Alternatively:
object basics:
// indented methods and fields go here
An App is a singleton that extends the pre-defined App object:
object basics extends App
{
// methods, fields, and inline code go
here
}
An app can be run from the programming environment.
Semicolons, empty parentheses, and curly braces are optional.
The return statement is optional (and should be avoided).
Here's the equivalent declarations in Java. Note the differences.
Double balance = 0.0;
Double c = 299792458; // not really a constant
Double square(Double x) { return x * x; }
A pure function has no side effects such as updating variables or printing. It just computes and returns a value.
A hybrid function returns a value and has side effects. We want to avoid these.
A procedure is a function that only has side effects. In Java procedures have a return type of void. In Scala a procedure has the return type Unit.
For example, basicTests is a procedure. It only prints stuff:
@main def basicTests =
println(name + " is "
+ age + " years old")
incAge
incAge
println(name + " is "
+ age + " years old")
In this version we declare the return type and use curly braces instead of indenting:
@main def
basicTests(): Unit = {
println(name
+ " is " + age + " years
old")
incAge
incAge
println(name
+ " is " + age + " years
old")
}
If we define basicTests with empty parentheses then it should be called with empty parentheses, otherwise leave them off:
basicTests() // def basicTests ) = ...
basicTests // def basicTests = ...
The body of a function can be a block:
def circleArea(radius: Double) = {
def square(x: Double) = x * x
MathConstants.pi *
square(radius)
}
Things defined in a block are only visible in that block. They come into existence when the block is executed and disappear when it exits.
The value of a block is the last expression in the block.
If a block is the body of a function, then the curly braces can be omitted:
def circleArea(radius: Double) =
def square(x: Double) = x * x
MathConstants.pi *
square(radius)
println(" balance = $" + balance)
versus
System.out.println(" balance = $" + balance)
A utility (aka service) is a singleton that contains a bunch of useful functions. We made use of Scala's math utility:
math.sqrt
math.exp
math.pow
math.E
// etc.
We can define our own utilities.
1. Implement a function that takes as inputs:
· principle = An amount of money to be invested
· rate = The annual rate of return
· periods = The number of periods per year interest will be compounded
· years = The number of years the investment will mature (with default value 1)
The function should return the value of the investment after it has matured.
Hint: The value of $100 invested at an annual rate of 12% compounded monthly for 10 years would be:
100 * (1 + .12/12)12 * 10 = $330.04
Test your function by displaying the values of an investment of $1 at an annual rate of 100% for 1 year compounded annually, monthly, weekly, daily, hourly, every second, and every millisecond.
2. The Twin Paradox demonstrates that time slows down the faster we go. Twin #1 takes off in a rocket ship travelling at velocity v and is gone for t seconds. Twin #2 stays home and times Twin #1's trip. Implement a function that takes two inputs: a number of seconds Twin #1 is gone and his velocity and returns how much time passes for Twin #2.
Hint: If Twin #1 travels at half the speed of light (c) for 100,000 seconds, then Twin #2's will age by:
100000 / sqrt(1 – (c/2)2 / c2) = 115470.05383792517 seconds
Test your function by computing the time dilations of 1 second assuming a velocity of 1000 m/sec, 1000000 m/sec, and c/2 m/sec.