Welcome to Simply Scala 2.8

      Scala is a modern computer programming language.
      Here you can discover more about its features in
      a simple interactive way.

Now available in French as well.
        
Creating user space...

Entering Code

All the examples in this tutorial can be run simply by clicking on them.

You can enter your own code by typing it into the box above. The code will be sent and run when you type Enter. You can type a lot of one-liners this way. However, if you open a code block with any form of braces the code will not be sent until the braces are matched and the cursor is positioned at the end of text. This allows you to write multi-line code and freely edit the code. You can always click on the Evaluate button or Ctrl Enter to force a send. Examples from other places can be entered using the regular cut and paste. The maximum text size is limited to about 2000 characters.

Already sent code can be recalled by using Ctrl with the up or down arrows. These you can then edit using the up/down arrows and send again. So you can try an example, then call it back, make changes, try different ideas and check how the syntax works.

Reset Button: This button resets your user space on the server. The server saves all the intermediate results you create so you may use them in later calculations. This takes some time. If you no longer need these results click on Reset. The server response to your requests will be improved. Previously entered text can still be recalled with the arrow keys.

Expressions

Simple arithmetic expressions work much as you would expect. The usual operators and precedence apply. Parentheses can be used to control the order of application.

1+2 3+4*(2-3) 23%5 // Modulus or Division Remainder 3.5*9.4+6/4

Scala understands different number types. 3.5 is a "double" while 6 is an "integer". Notice in this last case that integer division results in a truncation to an integer value. Scala will coerce values to the appropriate types in a mixed expression where possible.

The result of an expression may be stored in a variable. Variable names start with a character and can be followed by numbers or characters. "Golf1", "helpLine" and "Res4" are all examples of variable names. The result of an expression can be associated with a variable name. This association is signalled by a "var" or "val" keyword. "val" is used when the association is to be made once and not changed. For the time being you can use "var". Why are there "val" and "var"? "val" defines an immutable value and as you will learn later, is essential for functional style programming.

val pixel=34+5
var height=pixel+4
println(height)

Now try,

pixel=10 // this gives an error, trying to change a val
height+=4
println(height)

You can access previous results by using "res1", "res2", etc. Comments can be added to code at the end of a line with // or over several lines using a /* and */ pair. All comments will be ignored.

/*
  Example using res, and these comments
*/
res0 + " Scala"  // more comments on the line

There are a full set of bit manipulation operators too. These allow you to do bitwise operations.

3&2 // logical and 1|2 // logical or 1^2 // logical xor 1<<2 // shift left -24>>2 // shift right and preserve sign -14>>>2 // shift right and zero left bits

So now you already have quite a powerful on-line calculator but program flow control and functions for calculations that are to be repeated would be useful.

Base Types

Scala has a set of base types that are predefined. They are summarized as follows.

Byte 8-bit signed 2's complement integer (-128 to 127 inclusive)
Short 16-bit signed 2's complement integer (-32,768 to 32,767 inclusive)
Int 32-bit signed 2's complement integer (-2,147,483,648 to 2,147,483,647 inclusive)
Long 64-bit signed 2's complement integer (-2^63 to 2^63-1, inclusive)
Float 32-bit IEEE 754 single-precision float
Double 64-bit IEEE 754 double-precision float
Char 16-bit unsigned Unicode character
String a sequence of Unicode characters
Boolean true/false

if else

"if (cond) else" is the first of several flow control structures, the means of choosing to do one calculation rather than another based on some condition. If the condition is true one set of actions will be taken while if it is false another set will be done. The condition must be an expression that yields a boolean result, namely true or false. There are a number of comparison operators that do just that. Here are some of them that are useful with numbers. Later you will learn about others that are appropriate for other types of things.

1>2 // greater than 1<2 // less than 1==2 // equals 1>=2 // greater than or equal 1!=2 // not equal 1<=2 // less than or equal

With the if statement if the condition is true then the expression before the else is evaluated otherwise the expression after it is evaluated. Unlike in some languages the if else evaluates to a value.

if(1>2) 4 else 5 // greater than if (1<2) 6 else 7 // less than val try1=if (1==2) 8 else 9 // equals
val isBook = 6>=3
val price=16
val vol=10
val sale=if (isBook)price*vol else price/vol
sale

You may need to combine individual conditions in some way. There are two operators which do this for you. && meaning And. || meaning Or. These combine boolean values and are not equivalent to & | which combines bit values.

val isBook = 6>=3
val price=16
val vol=10
val sale=if (((isBook)&&(price>5))||(vol>30))price*vol else price/vol
sale

while

"while (cond) block/exp" allows you to repeat a block of code or an expression while the condition is true. First an expression.

var total=18
while(total < 17) total+=3

"do block/exp while (cond)" allows you to repeat a block of code or an expression while the condition is true. The condition is evaluated after doing each iteration.

var total=18
do{
total+=3
}while (total < 17)

Notice in this case that total end up as 21 rather than 18 in the previous example with the while. Here is while being used to calculate the Greatest Common Divisor or GCD.

// find the greatest common divisor
var x = 36
var y = 99
while (x != 0) {
val temp = x
x = y % x
y = temp
}
println("gcd is",y)

for

"for (range) block/exp" allows you to repeat a block of code for all the values in a range or iterate through the members of a collection.

for(i <- 1 to 4) println("hi five")

The value of i takes all the values from 1 to 4. If you want the end range value not to be included the until version should be used.

for(i <- 1 until 4) println(i)

Multi-dimensional iterations are elegantly handled using multiple ranges. Notice that the two ranges are separated by a semi-colon.

for(i <- 1 until 4 ; j <- 1 to 3) println(i,j)

"for" may also be used to iterate through collections. A string is a collection of characters so "for" may be used to iterate through it.

for(c<-"hello")println(c)

Literals

Literals allow you to define the value of one of the basic types in your code. They are pretty much the same as those you find in Java

Integers

There are four types of integer namely Int, Long, Short, and Byte. You can use literals expressed in different bases, they are decimal, hexadecimal, and octal. You signal which form you are using by the first characters.

decimal(base 10): Any number starting with a non-zero digit.

17 298

Hexadecimal(base 16): starts with a 0x or 0X and is followed by the hex digits 0 to 9, a to f or A to F

0x23 //hex = 35 dec 0x01FF //hex = 511 dec 0xcb17 //hex = 51991 dec

Octal(base 8): starts with a 0 and is followed by the octal digits 0 to 7

023 // octal = 19 dec 0777 // octal = 511 dec 0373 // octal = 251 dec

By default these will be created as type Int. You can force them to type Long by adding the letter "l" or "L".

0XFAF1L // hex long = 64241 035L

You can assign literals to Short or Byte variables. However, the value must be in the appropriate range for that type.

val abyte: Byte = 27 val ashort: Short = 1024 val errbyte: Byte = 128 // Error - not in range -128 to 127

Floating point

Floating point literals are numbers containing a decimal point. They must start with a non-zero digit and can be followed by E or e that prefixes an exponent indicating the power of 10 to use. Some examples are:-

9.876 val tiny= 1.2345e-5 val large = 9.87E45

By default floating literals are created as type Double but you can force them to type Float by adding the letter "f" or "F". Optionally "d" or "D" can be appended to a floating literal.

val sma = 1.5324F val ams = 3e5f

Character

Character literals are specified by any Unicode character in single quotes.

val chr = 'A'

You may also specify its value in several other ways.

Octal: An octal number between '\0' and '\377'.

val chr = '\101' // code for A

Unicode:A hexidecimal number between '\\u0000' and '\\uFFFF'

val chra = "\\u0041 is an A" val chre = "\\u0045 is a E"

Finally, there are also a few character literals represented by special escape sequences. These all start with a back slash. See reference for complete list.

Strings

A string literal is a sequence of characters enclosed in double quotes:

val helloW = "hello world" val someEsc = "\\\"\'"

Scala includes a special syntax to avoid these multiple escape characters. if you start and end a string with triple quotes (""") then all the characters such as newlines, quotation marks, and special characters are treated just like others.

println("""Welcome to Simply Scala.
Click 'About' for more information.""")

Boolean

The Boolean type has two possible values and the literals are true or false:

val isBig = true val isFool = false

Functions

Functions give you the capability to define calculations that you wish to repeat. A function is defined using the "def" key word. The example that follows creates a function that returns the max value for two integer values. Typically a function will return a value of some type. However, for some functions no return value is expected and in this case the return will be of type "unit" meaning no type.

def max(x: Int, y: Int): Int = {
if (x > y) x
else y
}

The name of the function,"max" in this case, follows the "def" then the parameters with their associated types within parentheses. Type annotation is added after the parameter name and preceded by a colon.This function has two parameters of type Int. Then the return type is defined following the colon, again Int in this case. Finally there is an equal sign and the function body enclosed in curly brackets. Once you have defined a function you can use it by calling it with the appropriate parameters.

max(6,7)

Functions can make recursive calls to themselves. Recursive functions form an alternative way of controlling iterations. In the following function that computes the Greatest Common Divisor no variables are required for intermediate values.

def gcd(x: Long, y: Long): Long =
if (y == 0) x else gcd(y, x % y)

Compare this to the earlier version written with a "while" loop.

gcd(96,128)

Everything is an Object

Scala is an Object Oriented language. The underlying premis, like other OO languages, is that there are objects that contain state and this state is manipulated or accessed by means of Methods. Method is the name given to functions that form the programmers interface to Objects. Objects are defined by the means of a class hierarchy. When you define a class you are also defining a new type of object. This new type and those already defined such as Int or Double are treated in a uniform way. The benefits of this uniformity, everything is an object, will soon become apparent. You can start by defining an object that represents a point.

class Point {
var x=0
var y=0
}

This is an abstract definition for the object. An instance of of the object can be created by using the "new" keyword.

val p=new Point

The variables within an Object can be accessed by using "."

p.x=3
p.y=4

You can retrieve the state in the same way.

println(p.x,p.y)

Setting the variables individually each time an instance of a new point is created is time consuming. By adding parameters to the class definition then the instance will be constructed with the desired values.

class Point( ix:Int,iy:Int){
var x=ix
var y=iy
}

And then create a point. Test it with println as before

val p=new Point(3,4)

Now suppose you would like to add two points together to create a new point. The equivalent of vector addition. Then you may add an appropriate method to do so.

class Point( ix:Int,iy:Int){
var x=ix
var y=iy
def vectorAdd(newpt:Point):Point={
  new Point(x+newpt.x,y+newpt.y)
  }
}

Given this definition two points can be created and their vector addition made.

val p1=new Point(3,4)
val p2=new Point(7,2)
val p3=p1.vectorAdd(p2)
println(p3.x,p3.y)

So far this looks pretty much as a Java programmer would expect. However,it would be more natural to write "p1+p2". In Scala you can do so. Method names can be composed using almost of the non-alphanumeric symbols. A few combinations are reserved and you will get an error if you try to use them. So the class can be rewritten to use "+" and a method for "-" created too.

class Point( ix:Int,iy:Int){
var x=ix
var y=iy
def +(newpt:Point):Point={
  new Point(x+newpt.x,y+newpt.y)
  }
def -(newpt:Point):Point={
  new Point(x-newpt.x,y-newpt.y)
  }
override def toString="Point("+x+","+y+")"
}
val p1=new Point(3,4)
val p2=new Point(7,2)
val p3=new Point(-2,2)

val p4=p1+p2-p3
println(p4.x,p4.y)

With this arrangement you can create a very natural looking vector calculus and a whole lot more readable than the traditional equivalent.

In Scala there is a further simplification of the class creation syntax with the introduction of "case classes". Taking the Point class above it can be expressed as a case class.

case class Point(x:Int,y:Int){
def +(newpt:Point)=Point(x+newpt.x,y+newpt.y)
def -(newpt:Point)=Point(x-newpt.x,y-newpt.y)
override def toString="Point("+x+","+y+")"
}
val p1=Point(3,4)
val p2=Point(7,2)
val p3=Point(-2,2)

p1+p2-p3

You notice that the explicit definition of the class fields are no longer required. You also see that the "new" is not required to create a new instance. The Scala compiler recognises that the new instance is required and creates it for you. Too note that in this case the curly brackets have been dropped in the "def". They are not required as the right hand side of the "def" is a simple expression and not statements. This is a general property of "def" and not just limited to case classes. Lastly see that the return type has been dropped in the function. Scala can infer what this is from the function definition.

This is just a small taste of why Scala is much more concisely written than the equivalent Java code. As you learn more Scala you will find many more code patterns that can be expressed in concise syntax too.

Everything is an object. As such, you may have wondered why the example above was not written more in Java style.

p1.+(p2.-(p3))

This is one of the nice syntactic features of Scala that helps to give clarity and uniformity to your code. You may leave out the parentheses and dots as Scala can infer were they belong. It is this carefully thought out syntax that allows you to implement Domain Specific Languages (DSLs). So all objects, including numbers are just objects with methods. For example you can perform the + method on the number 1 with the extended syntax too.

(1).+(2)

All the base types are in fact objects too that can be used and extended just like any other object.

Note the first set of parentheses around the "1" are required here to remove an ambiguity. "1." is a type Double and the result would be type Double rather than Int. Try making the change.

switch - Pattern match

You may already be familiar with the 'switch' with 'case' form used in many languages to allow multi-way branching on value. In Scala this concept is extended to provide full algebraic pattern matching using 'match'. However, the simple switch on value can also be represented easily with match.

def  decode(n:Int){
  n match {
    case 1 => println("One")
    case 2 => println("Two")
    case 5 => println("Five")
    case _ => println("Error")
  }
}
decode(2)

The '=>' symbol is used to separate the match pattern from the expression or block to be evaluated. The '_' symbol is used in Scala to mean wild-card or in this case match anything. The last case statement behaves like default in the classical switch. 'match', like most other functions returns a value so the above function could be written more concisely.

def  decode(n:Int){
  println(n match {
    case 1 => "One"
    case 2 => "Two"
    case 5 => "Five"
    case _ => "Error"
    }
  )
}
decode(3)

Unlike the traditional Java 'switch' the above mapping can easily be reversed.

def  encode(s:String){
  println(s match {
    case "One" => 1
    case "Two" => 2
    case "Five" => 5
	case _ => 0
    }
  )
}
encode("Five")

For the next example a binary tree is defined with internal nodes and values stored on leaf nodes. A function is created to find the value in the tree associated with the given key. Now see how the case pattern matching is used to determine the node type and bind names to the parameters, the lower case letters k,l,r and v. These are called pattern variables. They may also be constants, indicated by a starting uppercase letters or a literal. In which case the constant value is matched directly with the instances field value.

abstract class TreeN
case class InterN(key:String,left:TreeN,right:TreeN) extends TreeN
case class LeafN(key:String,value:Int) extends TreeN

def find(t:TreeN,key:String):Int={
     t match {
         case InterN(k,l,r) => find((if(k>=key)l else r),key)
         case LeafN(k,v) => if(k==key) v else 0
    }
}
// create a binary tree
val t=InterN("b",InterN("a",LeafN("a",1),LeafN("b",2)),LeafN("c",3))
/*       [b]
         / \
       [a] c,3
       / \
     a,1 b,2
*/

Note the use of the case class constructor to efficiently create a test binary tree. Now you can try the find.

find(t,"a") find(t,"c")

You may like to try wrapping this up into a Binary tree class, including member methods for adding, finding and deleting entries.

Suppose, for some reason, you would like to hide the key 'c' during the find. A simple modification to the find function does this nicely and illustrates the use of a constant match.

def find(t:TreeN,key:String):Int={
     t match {
         case InterN(k,l,r) => find((if(k>=key)l else r),key)
		 case LeafN("c",_) => 0
         case LeafN(k,v) => if(k==key) v else 0
    }
}

Notice the use of '_' as a wild card to match any value and remember that the case statements are evaluated in order.

Static Typing and Inferencing

Scala is a statically typed language, all the variables and functions have types that are fully defined at compile time. Using a variable or a function in a way inappropriate for the type will give compiler type errors. This means that the compiler can find many unintended programming errors for you before execution. However, you will have noticed that in the examples there are few type definitions. This is because Scala can usually infer what type a variable must be from the way you have used it.

For example, if you write 'val x=3' then the compiler infers that 'x' must be type Int as '3' is a integer literal. In a few situations the compiler will not be able to decide what you intended and will generate a type ambiguity error. In these cases you simply add the intended type annotation.

In general you must define function parameter types, however the compiler can usually infer the return type so it can usually be omitted. The exception to this rule is if you define recursive functions, ones that call themselves, you must define the return type.

Type inferencing dramatically reduces the amount of typing you must do and gives a great deal more clarity to the code. It is this type inferencing that gives Scala the feel of being dynamically typed.

Learning Scala and this tutorial

The aim of this tutorial is to give you a rapid overview of the basic features of Scala in a "hands-on" manner. It focuses on the essential things you need to know to get started but avoids going into to much depth. To fully understand Scala and discover more features click on 'Learn More Scala'. There you will find books and many other excellent learning materials to extend your knowledge. Then come back to Simply Scala to try the examples.

Or continue with the next part of the Tutorial by clicking on the Tab.

Functions are Objects too

In Scala everything is an object and so are functions. They may be passed as arguments, returned from other functions or stored in variables. This feature of Scala enables some very concise and elegant solutions to common programming problems as well as allowing extremely flexible program flow control structures. The Scala Actors make heavy use of this capability for supporting concurrent programming. However, list manipulation provides a good starting point for an introduction. For example, how do you find all the odd integers in a list? Here is a suitable list.

val lst=List(1,7,2,8,5,6,3,9,14,12,4,10)

Three list methods head,tail and :: will be used in these examples. From these you will see how many other useful list functions can be created. 'head' returns the first or leftmost element '1' in the above list, 'tail' returns the list with the first element, the '1' removed and :: returns a new list with an element added.

def odd(inLst:List[Int]):List[Int]={
  if(inLst==Nil) Nil
  else if(inLst.head%2==1) inLst.head::odd(inLst.tail)
  else odd(inLst.tail)
}
odd(lst)

A simple solution and to change this to return a list of the even integers is simple too.

def even(inLst:List[Int]):List[Int]={
  if(inLst==Nil) Nil
  else if(inLst.head%2==0) inLst.head::even(inLst.tail)
  else even(inLst.tail)
}
even(lst)

However, by passing a function that encapsulates the filtering condition as an argument a more general solution appears. First the filter condition function is defined.

def isodd(v:Int)= v%2==1

And then the modified filter function itself, a parameter is added to pass the function, just like any other object. Notice the form of the type declaration. The type will be a function with one Int parameter and will return a Boolean. Only functions of this type can be passed as arguments. In the function body 'cond' is used just like any other function.

def filter(inLst:List[Int],cond:(Int)=>Boolean):List[Int]={
  if(inLst==Nil) Nil
  else if(cond(inLst.head)) inLst.head::filter(inLst.tail,cond)
  else filter(inLst.tail,cond)
}
filter(lst,isodd)

Although the even case can be added in the same way a more concise version can be created using Anonymous functions. The def and name are dropped, creating an anonymous function definition that can be used directly as an argument. Notice the use of the => to separate the function parameter list from the body of the function.

filter(lst,(v:Int)=> v%2==0)

This filter function now does just what was required.

Taste of Generic Programming

Suppose you now want to create a filter for type Double. You could go through the code and simply replace all the type definitions of Int with Double. You would perhaps then call the new function filterD. For each new type you would go through the same exercise and end up with many versions of the same thing.

In Scala you can avoid this duplicated effort nicely by using a generic type in place of the actual ones. It is like using a variable to represent the type instead of the an actual type. The actual types get filled in later by the compiler where you make a call to the function.

Here 'T' is used, though any letters will do, in place of Int in filter and the function name is annotated with [T] to indicate that this is a generic function then the example becomes. The returned list has been reversed to give the same order as the input list.

def filter[T](inLst:List[T],cond:(T)=>Boolean):List[T]={
  if(inLst==Nil) Nil
  else if(cond(inLst.head)) inLst.head::filter(inLst.tail,cond)
  else filter(inLst.tail,cond)
}
filter(lst,(v:Int)=> v%2==0)

Then you can try using this generic version of filter with a list of Doubles to find all the elements greater than 5.

val lstd=List(1.5,7.4,2.3,8.1,5.6,6.2,3.5,9.2,14.6,12.91,4.23,10.04) filter(lstd,(v:Double)=> v>5)

Or with a list of strings to find those with a length greater than 3

val lsts=List("It's","a","far","far","better","thing","I","do","now") filter(lsts,(v:String)=> v.length>3)

In the reference you will find that lists have a filter function so you could equally write.

lsts.filter((v:String)=> v.length>3)

Generics will be explored more later but now, more about functions as objects.

More on 'Functions are objects'

The ability to carry out comprehensions, namely applying a function(s) for all members of a collection, is very powerful and leads to some very compact coding.

Many times you will want to pass quite simple functions as arguments and Scala has some nice shorthand that you will find useful. You have already seen that inferencing can help. The lst.filter example can be simplified as the compiler knows the argument must be a function with a String type. This allows you to drop the parentheses and type annotation.

lsts.filter(v=>v.length>3)

Since binary operators are frequently used, Scala provides you with an even nicer shorthand. The anonymous function '(x,y)=>x+y' can be replaced by '_+_' . Similarly 'v=>v.Method' can be replaced by '_.Method'. The _ acts as a place holder for the arguments and you are saved the chore of inventing repetitive boiler plate names. So once more lst.filter can be simplified to.

lsts.filter(_.length>3)

Reading other peoples Scala code you will come across these short forms quite often. Sometimes you must use the longer forms.

Here are some more examples of list manipulations with functions as arguments taken from the Reference section.

flatMap

lsts.flatMap(_.toList)

You see that flatMap takes a list and uses your given function to create a new list. In this case it 'flattens' your list of words into characters and concatenates these sublists to produce the result.

sort

The words could be sorted in ascending order using the sort method.

lsts.sort(_<_)

Or descending order

lsts.sort(_>_)

Or ignoring the case of the characters.

lsts.sort(_.toUpperCase<_.toUpperCase)

By passing the appropriate function you can create a whole family of sorts without having to re-code the sort itself. This is a really neat way to vary behavior without rewriting the whole method.

fold

foldLeft and foldRight allow you to combine adjacent list elements using an arbitrary function you pass. The process either starts from the left of the list or the right and provide a starting value. The option to start left or right allows you to choose which order you want to pass through the list. Starting with the list.

val lst=List(1,7,2,8,5,6,3,9,14,12,4,10) lst.foldLeft(0)(_+_)

With the passed '_+_' function the foldLeft function starts with 0 adds 1 to it. Next 7 is then added to this result and so on through the rest of the list.

removeDuplicates

Suppose you wish to know the unique letters that are in a list of words such as:-

val lstw=List("Once","more","unto","the","breach") lstw.flatMap(_.toList).map(_.toUpperCase).removeDuplicates.sort(_<_)

'flatMap' flattens all the words into a list of letters. 'map' converts them all to uppercase. All the duplicates are then removed and the result sorted into ascending order.

Tuples

It is often useful to return more than one value from a function. You can of course always create a class to do this but the typing overhead of making the definition becomes onerous. Scala allows you to create what are in effect anonymous classes in line. A tuple is simply a set of values enclosed in paretheses. A tuple can contain a mixture of types.

(3,'c')

The Tuple is an object so can accessed using the dot notation but since the fields have no names they are accessed using a name created with an underscore followed by the position index.

(3,'c')._1 (3,'c')._2

However the tuple deconstruction is more frequently used. For example,

val (i,c)=(3,'a')

You will see how this is used in the following program to create a letter frequency table from our words list.

The approach taken is to first flatten 'lstw', convert to upper case and then sort the the list of characters. Then a fold will be used to count the duplicate letters. You have already seen that a fold takes an input value and combines it successively with each list element to produce a new input value. In our case while the characters are the same a count needs to be incremented and when they differ the character and count need to be added to the freqency table.

The objective is to produce a list of tuples with two entries letter, Count. First create a sorted list of characters.

val ltrs=lstw.flatMap(_.toList).map(_.toUpperCase).sort(_<_)

Now the fold. The initial condition is an empty output frequency table, a list of tuples. The fold will expect a function that takes a list of tuples combines with a Char, the next character in the list, and returns a list of tuples.

ltrs.foldLeft(List[(Char,Int)]()){
  case ((prevchr,cnt)::tl,chr) if(prevchr==chr) =>(prevchr,cnt+1)::tl
  case (tbl,chr) => (chr,1)::tbl
}

To understand what is happening here perhaps some new pieces of Scala syntax need to be understood.

First, a sequence of cases (i.e. alternatives) in curly braces can be used anywhere a function literal can be used. It acts as a function with input parameter(s) and an implied match at the begining of the block. You can consider this as a convenient shorthand for the standard anonymous function form which would have been:-

(a,b)=>(a,b) match {case ...}

Second, you saw earlier that case is used to pattern match. Here that pattern matching is used to deconstruct our arguments and the list of tuples. '(prevchr,cnt)::tl' matches a list with a head element and tail and associates the names with those items. While 'chr' refers to the second fold arguement, the next list character.

Third, case syntactic pattern matches may not be a precise constraint, as is the case here so a pattern guard can be used. The guard starts with an if and can contain an arbitrary boolean expression. In this case the guard is used to restrict the case to just those where the previous character is the same as the current one.

So now we can read the expression as: For each character in the input list, if there is already an entry for it in the head of the frequency table, replace the head with a new head with the count incremented. In the other case simply add a new entry to the frequency table with a count of one.

Of course you could always use a more Java like approach too.

def IFreqCount(in:List[Char]):List[(Char,Int)]={
  var Tbl=List[(Char,Int)]()
  if(in.isEmpty)Tbl
  else{
    var prevChr=in.head
    var nxt=in.tail
    var Cnt=1
    while (!nxt.isEmpty){
      if(nxt.head==prevChr)Cnt+=1
      else {
        Tbl=(prevChr,Cnt)::Tbl
        Cnt=1
        prevChr=nxt.head
        }
      nxt=nxt.tail
      }
    (prevChr,Cnt)::Tbl
  }
}
IFreqCount(ltrs)

You will find this ability to treat functions as objects is very useful in all sorts of programming tasks, for example, passing callback functions in event driven IO, passing tasks to Actors in concurrent processing environments or in scheduling work loads. They often result in far more concise code as you see.

You will find the ability to use immutable data functions simplifies concurrent applications. It is well worth learning how to create them.

Next Steps

Here just a tiny part of the Scala libraries have been explored yet, by now, you are familiar with some essential Scala language features. Already you could write quite sophisticated programs in Scala. If you are already a Java programmer you can no doubt already see how you can use Scala with all the libraries from your existing Java environment too. Scala and Java integrate in a seamless way.

A good book is invaluable. Programming in Scala by Martin Odersky, Lex Spoon and Bill Venners is one excellent place to continue. Click on 'Learn More Scala' to learn more about that and other books. There are many excellent learning materials available to extend your knowledge and how you can download Scala and an IDE. Have fun!

And of course you can always come back to Simply Scala to try the examples...

These code snippets can give you a feel for how you can tackle a few interesting problems in Scala. Most of the snippets below are adapted from the ones you can find on the Scala-lang site. They are a little more advanced but in most cases can be understood quite quickly.

Abstract Classes

/* abstract classes */
  abstract class Buffer {
    type T; val element: T
  }
  abstract class SeqBuffer {
    type T; val element: Seq[T]; def length = element.length
  }
  def newIntBuffer(el: Int) = new Buffer {
    type T = Int; val element = el
  }
  def newIntBuffer(el: Int*) = new SeqBuffer {
    type T = Int; val element = el
  }

Use Examples:-

println(newIntBuffer(1).element) println(newIntBuffer(1, 2, 3).length)

Big Integers

/** Bigint's can be used seamlessly */
  def factorial(n: BigInt): BigInt =
    if (n == 0) 1 else n * factorial(n-1)

Use Examples:-

val f50 = factorial(50); val f49 = factorial(49)
println("50! = " + f50)
println("49! = " + f49) println("50!/49! = " + (f50 / f49))

A simple demonstration of the natural way Big Ints can be added to Scala expressions.

Complex Numbers

class Complex(val re: Double, val im: Double) {
    def + (that: Complex) =
      new Complex(re + that.re, im + that.im)
    def - (that: Complex) =
      new Complex(re - that.re, im - that.im)
    def * (that: Complex) =
      new Complex(re * that.re - im * that.im,
                  re * that.im + im * that.re)
    def / (that: Complex) = {
      val denom = that.re * that.re + that.im * that.im
      new Complex((re * that.re + im * that.im) / denom,
                  (im * that.re - re * that.im) / denom)
    }
    override def toString =
      re + (if (im < 0) "-" + (-im) else "+" + im) + "*i"
  }

Use Examples:-

val x = new Complex(2, 1); val y = new Complex(1, 3)
println(x + y)

Command line to upper case

/** Turn command line arguments to uppercase */
val args=List("Command","Line")
val res=for(a <- args) yield a.toUpperCase
println(res)

Adding a factorial method to Int

/* Adding ! as a method on int's */
  def fact(n: Int): BigInt =
    if (n == 0) 1 else fact(n-1) * n
  class Factorizer(n: Int) {
    def ! = fact(n)
  }
  implicit def int2fact(n: Int) = new Factorizer(n)

Use Examples:-

println("10! = " + (10!))

Adding a Sort to array objects

/* Defines a new method 'sort' for array objects */
  implicit def arrayWrapper[A](x: Array[A]) =
    new {
      def sort(p: (A, A) => Boolean) = {
        util.Sorting.stableSort(x, p); x
      }
    }

Use Examples:-

val x = Array(2, 3, 1, 4)
println("x = "+ x.sort((x: Int, y: Int) => x < y))

Using Maps

/** Maps are easy to use in Scala. */
val colors = Map("red" -> 0xFF0000,
                   "turquoise" -> 0x00FFFF,
                   "black" -> 0xFFFFFF,
                   "orange" -> 0xFF8040,
                   "brown" -> 0x804000)

def colormap(name:String):String={
      colors.get(name) match {
        case Some(code) =>
          name + " has code: " + code
        case None =>
          "Unknown color: " + name
      }
 }

Use Examples:-

colormap("black") colormap("orange")

Command line parsing

/** Basic command line parsing. */
def CmdLine(args:Array[String]){
    var verbose=false
    for (a <- args) a match {
      case "-h" | "-help"    =>
        println("Usage: scala Main [-help|-verbose]")
      case "-v" | "-verbose" =>
        verbose = true
      case x =>
        println("Unknown option: '" + x + "'")
    }
    if (verbose)
      println("How are you today?")
  }

Use Examples:-

CmdLine(Array[String]("-v","-help"))

Prime numbers

/** Print prime numbers less than 100, very inefficiently */
  def isPrime(n: Int) = (2 until n) forall (n % _ != 0)
  for (i <- 2 to 100 if isPrime(i)) println(i)

Sum a list

// Sum arguments
val args=List("12","14","16")
    try {
      val elems = args map Integer.parseInt
      println("The sum of my arguments is: " + elems.foldRight(0) (_ + _))
    } catch {
      case e: NumberFormatException =>
      println("Usage: scala Main <n1> <n2> ... ")
    }

Using Java varargs

/** Using Java varargs */
java.text.MessageFormat.format(
    "At {1,time} on {1,date}, there was {2} on planet {0}.",
    "Hoth", new java.util.Date(), "a disturbance in the Force")

Functions

Scala provides many enhanced functions. However, you can also use Java ones too. Here is a quick reference to a selection of useful functions to use while learning Scala. More can be found on the Java or Scala sites.

Strings

String manipulation is a frequent task. Here are some useful functions and definitions. In the descriptions all the function parameters are labeled in order so will be of the form P1.functionName(P2,P3...)

Escape characters for strings.

\n line feed

\b backspace

\t tab

\f form feed

\r carriage return

\" double quote

\' single quote

\\ backslash

Length

"four".length length of the string P1.

Comparison

note: use these instead of == and !=

"high".compareTo("higher") compares to P1. returns <0 if P1<P2, 0 if ==, >0 if P1>P2
"high".compareToIgnoreCase("High") same as above, but upper and lower case are same
"book".equals("loot") true if the two strings have equal values
"book".equalsIgnoreCase("BOOK") same as above ignoring case
"book".startsWith("bo") true if P1 starts with P2
"bookkeeper".startsWith("keep",4) true if P2 occurs starting at index P3
"bookmark".endsWith("ark") true if P1 ends with P2

Searching

Note: All "indexOf" methods return -1 if the string/char is not found. Indexes are all zero base.

"rerender".contains("ren") True if P2 can be found in P1.
"rerender".indexOf("nd") index of the first occurrence of String P2 in P1.
"rerender".indexOf("er",5) index of String P2 at or after position P3 in P1.
"rerender".indexOf('r') index of the first occurrence of char P2 in P1.
"rerender".indexOf('r',4) index of char P2 at or after position i in P1.
"rerender".lastIndexOf('e') index of last occurrence of P2 in P1.
"rerender".lastIndexOf('e',4) index of last occurrence of P2 on or before position P3 in P1.
"rerender".lastIndexOf("er") index of last occurrence of P2 in P1.
"rerender".lastIndexOf("er",5) index of last occurrence of P2 on or before position P3 in P1.

Getting parts

"polarbear".charAt(3) char at position P2 in P1.
"polarbear".substring(5) substring from index P2 to the end of P1.
"polarbear".substring(3,5) substring from index P2 to BEFORE index P3 of P1.

Creating a new string from the original

"Toni".toLowerCase new String with all chars lowercase
"Toni".toUpperCase new String with all chars uppercase
" Toni ".trim new String with whitespace deleted from front and back
"similar".replace('i','e') new String with all P2 characters replaced by character P3.
"ToniHanson".replace("on","er") new String with all P2 substrings replaced by P3.

Methods for Converting to String

String.valueOf(List(1,2,3)) Converts P2 to String, where P2 is any type value (primitive or object).

Maths

Here are some useful Maths functions. Remember to import them before using.

import Math._

Math Constants

Two common constants are defined in the Math class.

E Value of e, 2.718282..., base of the natural logarithms.
Pi Value of pi, 3.14159265 ....

Math Methods

Trigonometric Methods

All trigonometric method parameters are measured in radians, the normal mathematical system of angles, and not in degrees, the normal human angular measurement system. Use the toRadians or toDegrees methods to convert between these systems, or use the fact that there are 2*PI radians in 360 degrees. In addition to the methods below, the arc methods are also available.

sin(Pi/6) sine of P1.
cos(Pi/6) cosine of P1.
tan(Pi/6) tangent of P1.
toRadians(45) P1 (angle in degrees) converted to radians.
toDegrees(Pi/2) P1 (angle in radians) converted to degrees.

Exponential Methods

The two basic functions for logarithms and power are available. These both use the base e (Math.E) as is the usual case in mathematics.

exp(Pi) e (2.71...) to the power P1.
pow(6,3) P1 raised to P2.
log(10) logarithm of P1 to base e.

Misc Methods

sqrt(225) square root of P1.
abs(-7) absolute value of P1 with same type as the parameter: int, long, float, or double.
max(8,3) maximum of P1 and P2 with same type as the parameter: int, long, float, or double.
min(8,3) minimum of P1 and P2 with same type as the parameter: int, long, float, or double.

Integer Related Methods

The following methods translate floating point values to integer values, although these values may still be stored in a double.

floor(3.12) closest integer-valued double which is equal to or less than P1.
ceil(3.12) closest integer-valued double which is equal to or greater than P1.
rint(3.51) closest integer-valued double to P1.
round(3.48) long which is closest in value to the double P1.
round(2.6) int which is closest in value to the float P1.

Random Numbers

random Returns a pseudo random number in the range, 0.0 <= x < 1.0.

Operator Precedence

(all other special characters)

* / %

+ - :

= !

< >

&

^

|

(all letters)

(all assignment operators) eg = += -= *= /= etc

Operator Associativity The associativity of an operator in Scala is determined by its last character. Any method that ends in a ':' character is invoked on its right operand, passing in the left operand. Methods that end in any other character are the other way around. They are invoked on their left operand, passing in the right operand. So a * b yields a.*(b), but a ::: b yields b.:::(a).

Lists

Lists provide a common sequence structure that is used for many functional style algorithms. The following functions enable Lists to be manipulated easily and effectively. The first example creates the List that is used for other examples.

Note: _+_ is a shorthand for an anonymous function x,y=>x+y. Since binary operators are frequently used this is a nice abbreviation. Similarly _.Method is shorthand for v=>v.Method

val lst = "Tempus" :: "fugit" ::"irreparabile" :: Nil Creates a new List[String] with the three values "Tempus", "fugit", and "irreparabile"
List() or use Nil for the empty List
List("Time", "flys", "irrecoverably") Creates a new List[String] with the three entries "Time", "flys", and "irrecoverably"
List("tick", "tock") ::: List("cuk", "oo") Operator that concatenates two lists
lst(2) Returns the item at 0 based index 2 in lst
lst.count(str => str.length == 5) Counts the string elements in lst that are of length 5
lst.exists(str => str == "irreparabile") Determines whether a string element exists in lst that has the value "irreparabile"
lst.drop(2) Returns lst without the first 2 elements (returns List("irreparabile"))
lst.dropRight(2) Returns lst without the rightmost 2 elements (returns List("Tempus"))
lst.filter(str => str.length == 5) Returns a list of all elements, in order, from lst that have length 5
lst.flatMap(_.toList) Applies the given function f to each element of this list, then concatenates the results
lst.forall(str =>str.endsWith("e")) true if all elements in lst end with the letter "e" else false
lst.foreach(str => print(str)) Executes the print function for each of the strings in the lst
lst.foreach(print) Same as the previous, but more concise
lst.head Returns the first item in lst
lst.tail Returns a list that is lst without its first item
lst.init Returns a list of all but the last element in lst
lst.isEmpty true if lst is empty
lst.last Returns the last item in lst
lst.length Returns the number of items in the lst
lst.map(str => str + "?") Returns a list created by adding "?" to each string item in lst
lst.mkString(", ") Makes a string with the elements of the list
lst.remove(str => str.length == 4) Returns a list of all items in lst, in order, excepting any of length 4
List(1,6,2,1,6,3).removeDuplicates Removes redundant elements from the list. Uses the method == to decide.
lst.reverse Returns a list containing all elements of the lst list in reverse order
lst.sort((str, t) => str.toLowerCase < t.toLowerCase) Returns a list containing all items of lst in alphabetical order in lowercase.

Some more useful list operations. First define a list of integers to use.

val lsti=List(1,7,2,8,5,6,3,9,14,12,4,10)
lsti.foldLeft(0)(_+_) Combines elements of list using a binary function starting from left, initial one with a 0 in this case.
lsti.foldRight(0x20)(_|_) Combines elements of list using a binary function starting from Right, initial one with a hex 20 in this case.

Scala Glossary

This glossary has been reprinted with permission from the book Programming in Scala by Martin Odersky, Lex Spoon, and Bill Venners.

algebraic data type

A type defined by providing several alternatives, each of which comes with its own constructor. It usually comes with a way to decompose the type through pattern matching. The concept is found in specification languages and functional programming languages. Algebraic data types can be emulated in Scala with case classes.

alternative

A branch of a match expression. It has the form "case pattern => expression." Another name for alternative is case.

annotation

An annotation appears in source code and is attached to some part of the syntax. Annotations are computer processable, so you can use them to effectively add an extension to Scala.

anonymous class

An anonymous class is a synthetic subclass generated by the Scala compiler from a new expression in which the class or trait name is followed by curly braces. The curly braces contains the body of the anonymous subclass, which may be empty. However, if the name following new refers to a trait or class that contains abstract members, these must be made concrete inside the curly braces that define the body of the anonymous subclass.

anonymous function

Another name for function literal.

apply

You can apply a method, function, or closure to arguments, which means you invoke it on those arguments.

argument

When a function is invoked, an argument is passed for each parameter of that function. The parameter is the variable that refers to the argument. The argument is the object passed at invocation time. In addition, applications can take (command line) arguments that show up in the Array[String] passed to main methods of singleton objects.

assign

You can assign an object to a variable. Afterwards, the variable will refer to the object.

auxiliary constructor

Extra constructors defined inside the curly braces of the class definition, which look like method definitions named this, but with no result type.

block

One or more expressions and declarations surrounded by curly braces. When the block evaluates, all of its expressions and declarations are processed in order, and then the block returns the value of the last expression as its own value. Blocks are commonly used as the bodies of functions, for expressions, while loops, and any other place where you want to group a number of statements together. More formally, a block is an encapsulation construct for which you can only see side effects and a result value. The curly braces in which you define a class or object do not, therefore, form a block, because fields and methods (which are defined inside those curly braces) are visible from the outside. Such curly braces form a template.

bound variable

A bound variable of an expression is a variable that's both used and defined inside the expression. For instance, in the function literal expression (x: Int) => (x, y), both variables x and y are used, but only x is bound, because it is defined in the expression as an Int and the sole argument to the function described by the expression.

by-name parameter

A parameter that is marked with a => in front of the parameter type, e.g., (x: => Int). The argument corresponding to a by-name parameter is evaluated not before the method is invoked, but each time the parameter is referenced by name inside the method. If a parameter is not by-name, it is by-value.

by-value parameter

A parameter that is not marked with a => in front of the parameter type, e.g., (x: Int). The argument corresponding to a by-value parameter is evaluated before the method is invoked. Byvalue parameters contrast with by-name parameters.

class

Defined with the class keyword, a class may either be abstract or concrete, and may be parameterized with types and values when instantiated. In "new Array[String](2)", the class being instantiated is Array and the type of the value that results is Array[String]. A class that takes type parameters is called a type constructor. A type can be said to have a class as well, as in: the class of type Array[String] is Array.

closure

A function object that captures free variables, and is said to be "closed" over the variables visible at the time it is created.

companion class

A class that shares the same name with a singleton object defined in the same source file. The class is the singleton object's companion class.

companion object

A singleton object that shares the same name with a class defined in the same source file. Companion objects and classes have access to each other's private members. In addition, any implicit conversions defined in the companion object will be in scope anywhere the class is used.

contravariant

A contravariant annotation can be applied to a type parameter of a class or trait by putting a minus sign () before the type parameter. The class or trait then subtypes contravariantly with— in the opposite direction as—the type annotated parameter. For example, Function1 is contravariant in its first type parameter, and so Function1[Any, Any] is a subtype of Function1[String, Any].

covariant

A covariant annotation can be applied to a type parameter of a class or trait by putting a plus sign (+) before the type parameter. The class or trait then subtypes covariantly with—in the same direction as—the type annotated parameter. For example, List is covariant in its type parameter, so List[String] is a subtype of List[Any].

currying

A way to write functions with multiple parameter lists. For instance def f(x: Int)(y: Int) is a curried function with two parameter lists. A curried function is applied by passing several arguments lists, as in: f(3)(4). However, it is also possible to write a partial application of a curried function, such as f(3).

declare

You can declare an abstract field, method, or type, which gives an entity a name but not an implementation. The key difference between declarations and definitions is that definitions establish an implementation for the named entity, declarations do not.

define

To define something in a Scala program is to give it a name and an implementation. You can define classes, traits, singleton objects, fields, methods, local functions, local variables, etc. Because definitions always involve some kind of implementation, abstract members are declared not defined.

direct subclass

A class is a direct subclass of its direct superclass.

direct superclass

The class from which a class or trait it is immediately derived, the nearest class above it in its inheritance hierarchy. If a class Parent is mentioned in a class Child's optional extends clause, then Parent is the direct superclass of Child. If a trait is mentioned in Child's extends clause, the trait's direct superclass is the Child's direct superclass. If Child has no extends clause, then AnyRef is the direct superclass of Child. If a class's direct superclass takes type parameters, for example class Child extends Parent[String], the direct superclass of Child is still Parent, not Parent[String]. On the other hand, Parent[String] would be the direct supertype of Child. See supertype for more discussion of the distinction between class and type.

equality

When used without qualification, equality is the relation between values expressed by ‘=='. See also reference equality.

existential type

An existential type includes references to type variables that are unknown. For example, Array[T] forSome { type T } is an existential type. It is an array of T, where T is some completely unknown type. All that is assumed about T is that it exists at all. This assumption is weak, but it means at least that an Array[T] forSome { type T } is indeed an array and not a banana.

expression

Any bit of Scala code that yields a result. You can also say that an expression evaluates to a result or results in a value.

filter

An if followed by a boolean expression in a for expression. In for(i <1 to 10; if i % 2 == 0), the filter is "if i % 2 == 0". The value to the right of the if is the filter expression.

filter expression

A filter expression is the boolean expression following an if in a for expression. In for(i <1 to 10; if i % 2 == 0), the filter expression is "i % 2 == 0".

first-class function

Scala supports first-class functions, which means you can express functions in function literal syntax, i.e., (x: Int) => x + 1, and that functions can be represented by objects, which are called function values.

for comprehension

Another name for for expression.

free variable

A free variable of an expression is a variable that's used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x, y), both variables x and y are used, but only y is a free variable, because it is not defined inside the expression.

function

A function can be invoked with a list of arguments to produce a result. A function has a parameter list, a body, and a result type. Functions that are members of a class, trait, or singleton object are called methods. Functions defined inside other functions are called local functions. Functions with the result type of Unit are called procedures. Anonymous functions in source code are called function literals. At run time, function literals are instantiated into objects called function values.

function literal

A function with no name in Scala source code, specified with function literal syntax. For example, (x: Int, y: Int) => x + y.

function value

A function object that can be invoked just like any other function. A function value's class extends one of the FunctionN traits (e.g., Function0, Function1) from package scala, and is usually expressed in source code via function literal syntax. A function value is "invoked" when its apply method is called. A function value that captures free variables is a closure.

functional style

The functional style of programming emphasizes functions and evaluation results and deemphasizes the order in which operations occur. The style is characterized by passing function values into looping methods, immutable data, methods with no side effects. It is the dominant paradigm of languages such as Haskell and Erlang, and contrasts with the imperative style.

generator

A generator defines a named val and assigns to it a series of values in a for expression. For example, in for(i <1 to 10), the generator is "i <1 to 10". The value to the right of the <is the generator expression.

generator expression

A generator expression generates a series of values in a for expression. For example, in for(i <1 to 10), the generator expression is "1 to 10".

generic class

A class that takes type parameters. For example, because scala.List takes a type parameter, scala.List is a generic class.

generic trait

A trait that takes type parameters. For example, because trait scala.collection.Set takes a type parameter, it is a generic trait.

helper function

A function whose purpose is to provide a service to one or more other functions nearby. Helper functions are often implemented as local functions.

helper method

A helper function that's a member of a class. Helper methods are often private.

immutable

An object is immutable if its value cannot be changed after it is created in any way visible to clients. Objects may or may not be immutable.

imperative style

The imperative style of programming emphasizes careful sequencing of operations so that their effects happen in the right order. The style is characterized by iteration with loops, mutating data in place, and methods with side effects. It is the dominant paradigm of languages such as C, C++, C# and Java, and contrasts with the functional style.

initialize

When a variable is defined in Scala source code, you must initialize it with an object.

instance

An instance, or class instance, is an object, a concept that exists only at run time.

instantiate

To instantiate a class is to make a new object from the class, an action that happens only at run time.

invariant

Invariant is used in two ways. It can mean a property that always holds true when a data structure is well-formed. For example, it is an invariant of a sorted binary tree that each node is ordered before its right subnode, if it has a right subnode. Invariant is also sometimes used as a synonym for nonvariant: "class Array is invariant in its type parameter."

invoke

You can invoke a method, function, or closure on arguments, meaning its body will be executed with the specified arguments.

JVM

The JVM is the Java Virtual Machine, or runtime, that hosts a running Scala program.

literal

1, "One", and (x: Int) => x + 1 are examples of literals. A literal is a shorthand way to describe an object, where the shorthand exactly mirrors the structure of the created object.

local function

A local function is a def defined inside a block. To contrast, a def defined as a member of a class, trait, or singleton object is called a method.

local variable

A local variable is a val or var defined inside a block. Although similar to local variables, parameters to functions are not referred to as local variables, but simply as parameters or "variables" without the "local."

member

A member is any named element of the template of a class, trait, or singleton object. A member may be accessed with the name of its owner, a dot, and its simple name. For example, top-level fields and methods defined in a class are members of that class. A trait defined inside a class is a member of its enclosing class. A type defined with the type keyword in a class is a member of that class. A class is a member of the package test.views which is it defined. By contrast, a local variable or local function is not a member of its surrounding block.

message

Actors communicate with each other by sending each other messages. Sending a message does not interrupt what the receiver is doing. The receiver can wait until it has finished its current activity and its invariants have been reestablished.

meta-programming

Meta-programming software is software whose input is itself software. Compilers are meta-programs, as are tools like scaladoc. Meta-programming software is required in order to do anything with an annotation.

method

A method is a function that is a member of some class, trait, or singleton object.

mixin

Mixin is what a trait is called when it is being used in a mixin composition. In other words, in "trait Hat," Hat is just a trait, but in "new Cat extends AnyRef with Hat," Hat can be called a mixin. When used as a verb, "mix in" is two words. For example, you can mix traits into classes or other traits.

mixin composition

The process of mixing traits into classes or other traits. Mixin composition differs from traditional multiple inheritance in that the type of the super reference is not known at the point the trait is defined, but rather is determined anew each time the trait is mixed into a class or other trait.

modifier

A keyword that qualifies a class, trait, field, or method definition in some way. For example, the private modifier indicates that a class, trait, field, or method being defined is private.

multiple definitions

The same expression can be assigned in multiple definitions if you use the syntax val v1, v2, v3 = exp.

nonvariant

A type parameter of a class or trait is by default nonvariant. The class or trait then does not subtype when that parameter changes. For example, because class Array is nonvariant in its type parameter, Array[String] is neither a subtype nor a supertype of Array[Any].

operation

In Scala, every operation is a method call. Methods may be invoked in operator notation, such as b + 2, and when in that notation, + is an operator.

parameter

Functions may take zero to many parameters. Each parameter has a name and a type. The distinction between parameters and arguments is that arguments refer to the actual objects passed when a function is invoked. Parameters are the variables that refer to those passed arguments.

parameterless function

A function that takes no parameters, which is defined without any empty parentheses. Invocations of parameterless functions may not supply parentheses. This supports the uniform access principle, which enables the def to be changed into a val without requiring a change to client code.

parameterless method

A parameterless method is a parameterless function that is a member of a class, trait, or singleton object.

parametric field

A field defined as a class parameter.

partially applied function

A function that's used in an expression and that misses some of its arguments. For instance, if function f has type Int => Int => Int, then f and f(1) are partially applied functions.

path-dependent type

A type like swiss.cow.Food. The swiss.cow part is a path that forms a reference to an object. The meaning of the type is sensitive to the path you use to access it. The types swiss.cow.Food and fish.Food, for example, are different types.

pattern

In a match expression alternative, a pattern follows each case keyword and precedes either a pattern guard or the => symbol.

pattern guard

In a match expression alternative, a pattern guard can follow a pattern. For example, in "case x if x % 2 == 0 => x + 1", the pattern guard is "if x % 2 == 0". A case with a pattern guard will only be selected if the pattern matches and the pattern guard yields true.

predicate

A predicate is a function with a Boolean result type.

primary constructor

The main constructor of a class, which invokes a superclass constructor, if necessary, initializes fields to passed values, and executes any top-level code defined between the curly braces of the class. Fields are initialzed only for value parameters not passed to the superclass constructor, except for any that are not used in the body of the class and can therefore by optimized away.

procedure

A procedure is a function with result type of Unit, which is therefore executed solely for its side effects. reassignable A variable may or may not be reassignable. A var is reassignable while a val is not.

recursive

A function is recursive if it calls itself. If the only place the function calls itself is the last expression of the function, then the function is tail recursive.

reference

A reference is the Java abstraction of a pointer, which uniquely identifies an object that resides on the JVM's heap. Reference type variables hold references to objects, because reference types (instances of AnyRef) are implemented as Java objects that reside on the JVM's heap. Value type variables, by contrast, may sometimes hold a reference (to a boxed wrapper type) and sometimes not (when the object is being represented as a primitive value). Speaking generally, a Scala variable refers to an object. The term "refers" is more abstract than "holds a reference." If a variable of type scala.Int is currently represented as a primitive Java int value, then that variable still refers to the Int object, but no reference is involved.

reference equality

Reference equality means that two references identify the very same Java object. Reference equality can be determined, for reference types only, by calling eq in AnyRef. (In Java programs, reference equality can be determined using == on Java reference types.)

reference type

A reference type is a subclass of AnyRef. Instances of reference types always reside on the JVM's heap at run time.

referential transparency

A property of functions that are independent of temporal context and have no side effects. For a particular input, an invocation of a referentially transparent function can be replaced by its result without changing the program semantics.

refers

A variable in a running Scala program always refers to some object. Even if that variable is assigned to null, it conceptually refers to the Null object. At runtime, an object may be implemented by a Java object or a value of a primitive type, but Scala allows programmers to think at a higher level of abstraction about their code as they imagine it running. See also reference.

result

An expression in a Scala program yields a result. The result of every expression in Scala is an object.

result type

A method's result type is the type of the value that results from calling the method. (In Java, this concept is called the return type.)

return

A function in a Scala program returns a value. You can call this value the result of the function. You can also say the function results in the value. The result of every function in Scala is an object.

runtime

The Java Virtual Machine, or JVM, that hosts a running Scala program. Runtime encompasses both the virtual machine, as defined by the Java Virtual Machine Specification, and the runtime libraries of the Java API and the standard Scala API. The phrase at run time (with a space between run and time) means when the program is running, and contrasts with compile time.

runtime type

The type of an object at run time. To contrast, a static type is the type of an expression at compile time. Most runtime types are simply bare classes with no type parameters. For example, the runtime type of "Hi" is String, and the runtime type of (x: Int) => x + 1 is Function1. Runtime types can be tested with isInstanceOf.

script

A file containing top level definitions and statements, which can be run directly with scala without explicitly compiling. A script must end in an expression, not a definition.

selector

The value being matched on in a match expression. For example, in "s match { case _ => }", the selector is s.

self type

A self type of a trait is the assumed type of this, the receiver, to be used within the trait. Any concrete class that mixes in the trait must ensure that its type conforms to the trait's self type. The most common use of self types is for dividing a large class into several traits.

semi-structured data

XML data is semi-structured. It is more structured than a flat binary file or text file, but it does not have the full structure of a programming language's data structures.

serialization

You can serialize an object into a byte stream which can then be saved to files or transmitted over the network. You can later deserialize the byte stream, even on different computer, and obtain an object that is the same as the original serialized object.

shadow

A new declaration of a local variable shadows one of the same name in an enclosing scope.

signature

Signature is short for type signature.

singleton object

An object defined with the object keyword. Each singleton object has one and only one instance. A singleton object that shares its name with a class, and is defined in the same source file as that class, is that class's companion object. The class is its companion class. A singleton object that doesn't have a companion class is a standalone object.

standalone object

A singleton object that has no companion class. statement An expression, definition, or import, i.e., things that can go into a template or a block in Scala source code.

static type

See type.

subclass

A class is a subclass of all of its superclasses and supertraits.

subtrait

A trait is a subtrait of all of its supertraits.

subtype

The Scala compiler will allow any of a type's subtypes to be used as a substitute wherever that type is required. For classes and traits that take no type parameters, the subtype relationship mirrors the subclass relationship. For example, if class Cat is a subclass of abstract class Animal, and neither takes type parameters, type Cat is a subtype of type Animal. Likewise, if trait Apple is a subtrait of trait Fruit, and neither takes type parameters, type Apple is a subtype of type Fruit. For classes and traits that take type parameters, however, variance comes into play. For example, because abstract class List is declared to be covariant in its lone type parameter (i.e., List is declared List[+A]), List[Cat] is a subtype of List[Animal], and List[Apple] a subtype of List[Fruit]. These subtype relationships exist even though the class of each of these types is List. By contrast, because Set is not declared to be covariant in its type parameter (i.e., Set is declared Set[A] with no plus sign), Set[Cat] is not a subtype of Set[Animal]. A subtype should correctly implement the contracts of its supertypes, so that the Liskov Substitution Principle applies, but the compiler only verifies this property at the level of type checking.

superclass

A class's superclasses include its direct superclass, its direct superclass's direct superclass, and so on, all the way up to Any.

supertrait

A class's or trait's supertraits, if any, include all traits directly mixed into the class or trait or any of its superclasses, plus any supertraits of those traits.

supertype

A type is a supertype of all of its subtypes.

synthetic class

A synthetic class is generated automatically by the compiler rather than being written by hand by the programmer.

tail recursive

A function is tail recursive if the only place the function calls itself is the last operation of the function.

target typing

Target typing is a form of type inference that takes into account the type that's expected. In nums.filter((x) => x > 0), for example, the Scala compiler infers type of x to be the element type of nums, because the filter method invokes the function on each element of nums.

template

A template is the body of a class, trait, or singleton object definition. It defines the type signature, behavior and initial state of the class, trait, or object.

trait

A trait, which is defined with the trait keyword, is like an abstract class that cannot take any value parameters and can be "mixed into" classes or other traits via the process known as mixin composition. When a trait is being mixed into a class or trait, it is called a mixin. A trait may be parameterized with one or more types. When parameterized with types, the trait constructs a type. For example, Set is a trait that takes a single type parameter, whereas Set[Int] is a type. Also, Set is said to be "the trait of" type Set[Int].

type

Every variable and expression in a Scala program has a type that is known at compile time. A type restricts the possible values to which a variable can refer, or an expression can produce, at run time. A variable or expression's type can also be referred to as a static type if necessary to differentiate it from an object's runtime type. In other words, "type" by itself means static type. Type is distinct from class because a class that takes type parameters can construct many types. For example, List is a class, but not a type. List[T] is a type with a free type parameter. List[Int] and List[String] are also types (called ground types because they have no free type parameters). A type can have a "class" or "trait." For example, the class of type List[Int] is List. The trait of type Set[String] is Set.

type constraint

Some annotations are type constraints, meaning that they add additional limits, or constraints, on what values the type includes. For example, @positive could be a type constraint on the type Int, limiting the type of 32-bit integers down to those that are positive. Type constraints are not checked by the standard Scala compiler, but must instead be checked by an extra tool or by a compiler plugin.

type constructor

A class or trait that takes type parameters.

type parameter

A parameter to a generic class or generic method that must be filled in by a type. For example, class List is defined as "class List[T] { . . . ", and method identity, a member of object Predef, is defined as "def identity[T](x:T) = x". The T in both cases is a type parameter.

type signature

A method's type signature comprises its name, the number, order, and types of its parameters, if any, and its result type. The type signature of a class, trait, or singleton object comprises its name, the type signatures of all of its members and constructors, and its declared inheritance and mixin relations.

uniform access principle

The uniform access principle states that variables and parameterless functions should be accessed using the same syntax. Scala supports this principle by not allowing parentheses to be placed at call sites of parameterless functions. As a result, a parameterless function definition can be changed to a val, or vice versa, without affecting client code.

unreachable

At the Scala level, objects can become unreachable, at which point the memory they occupy may be reclaimed by the runtime. Unreachable does not necessarily mean unreferenced. Reference types (instances of AnyRef) are implemented as objects that reside on the JVM's heap. When an instance of a reference type becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. Value types (instances of AnyVal) are implemented as both primitive type values and as instances of Java wrapper types (such as java.lang.Integer), which reside on the heap. Value type instances can be boxed (converted from a primitive value to a wrapper object) and unboxed (converted from a wrapper object to a primitive value) throughout the lifetime of the variables that refer to them. If a value type instance currently represented as a wrapper object on the JVM's heap becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. But if a value type currently represented as a primitive value becomes unreachable, then it does not become unreferenced, because it does not exist as an object on the JVM's heap at that point in time. The runtime may reclaim memory occupied by unreachable objects, but if an Int, for example, is implemented at run time by a primitive Java int that occupies some memory in the stack frame of an executing method, then the memory for that object is "reclaimed" when the stack frame is popped as the method completes. Memory for reference types, such as Strings, may be reclaimed by the JVM's garbage collector after they become unreachable.

unreferenced

See unreachable.

value

The result of any computation or expression in Scala is a value, and in Scala, every value is an object. The term value essentially means the image of an object in memory (on the JVM's heap or stack).

value type

A value type is any subclass of AnyVal, such as Int, Double, or Unit. This term has meaning at the level of Scala source code. At runtime, instances of value types that correspond to Java primitive types may be implemented in terms of primitive type values or instances of wrapper types, such as java.lang.Integer. Over the lifetime of a value type instance, the runtime may transform it back and forth between primitive and wrapper types (i.e., to box and unbox it).

variable

A named entity that refers to an object. A variable is either a val or a var. Both vals and vars must be initialized when defined, but only vars can be later reassigned to refer to a different object.

variance

A type parameter of a class or trait can be marked with a variance annotation, either covariant (+) or contravariant (). Such variance annotations indicate how subtyping works for a generic class or trait. For example, the generic class List is covariant in its type parameter, and thus List[String] is a subtype of List[Any]. By default, i.e., absent a + or annotation, type parameters are nonvariant.

yield

An expression can yield a result. The yield keyword designates the result of a for expression.