Warning! Your browser doesn't support the features required.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Scala Tour

Start your Exciting Scala Tour

Hello World

Scala is a popular functional/object-oriented programming language built on top of the Java virtual machine (JVM).

The tour will help you to know the powerful features about Scala. And you could learn how to use them effectively through experimentation.

The tour is interactive. Click the Run button now to compile and run the program on a remote server. The result is displayed below the code. You can edit it and run your own code. (It may be a little slow when you first run, but it would faster next)

Use the space bar or arrow keys to navigate

BasicStart

Content (Basic)

Expressions and Values

In Scala, almost everything is an expression.

println("hello wolrd")

is an expression,

"hello"+" world"

is also an expression.

Constants can be created with val, and variables can be created with var. More constants are better.

First class Functions

You can create functions with def. And the function body is an expression.

When the body is a block expression, it returns the value of the last line. So there's no need to use the return keyword

And like values, functions can also be assigned using var or val So it can be passed as an argument to another function.

Loan Pattern

For functions which can be passed as arguments, the 'Loan' pattern is easy to implement.

This example reads the self pid from /proc/self/stat.

Because the 'withScanner' function encapsulates the 'try-finally' block,there's no need to call 'close()' any more.。

PS: the expression's return type is 'Unit' when it doesn't return a value.

Call by Name

This example shows the call by name, When the last line tries to calculate '1 / 0', the program will throw an exception.

Try to change

def log(msg: String)

to

def log(msg: => String)

The program will not throw an exception because it has been changed to call-by-name

Call-by-name means that the argument will be calculated when it is actually called. So the '1 / 0' will be skipped.

Call-by-name can reduce the useless calculation and exception.

Define Class

The 'class' keyword defines a class, and the 'new' keyword creates an instance.

The fields can be also defined in class, like the 'firstName' and 'lastName'.These are automatically generated from the constructor's arguments.

Methods can be defined with def, and fields can be defined with val or var

The function name can be any characters like +,-,*,/.

Try to change

obama.age_=(51)

to

obama.age = 51

It looks like accessing a variable.

Duck Typing

When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.

This example uses

{ def close(): Unit }

as the type of argument.So any class contains methods 'close()' can be passed.

And there's no need to use 'inherit'。

Currying

This example is similar to the previous one.The difference between them is this one leverages currying technology

def add(x:Int, y:Int) = x + y

is a normal function

def add(x:Int) = (y:Int) => x + y

is a curried function.The return value is a function expression.

 def add(x:Int)(y:Int) = x + y

is syntactic sugar

Currying can let our code look like it is part of the language.

Try to change the withclose(...)(...) to withclose(...){...}

Generic

The sample before can be more simplified with generics.

Try to change

"123456"

to

123456

Although the type of msg changed from String to Int, the program still compiles.

Traits

Traits look like Java's interfaces, but with function blocks. One class can extend several traits using the with keyword.

This example extends java.util.ArrayList with a foreach loop.

Try to append after ForEachAble[Int] with

with JsonAble

to extend the ability of toJson

FunctionalStart

Content (Functional)

Pattern Matching

Pattern Matching is more flexible than switch-case and simpler than if-else.

This example shows a Fibonacci function implemented with pattern matching. The case keyword matches on a value. The case _ means it can match anything.

Try to change

case n: Int

to

case n: Int if (n > 1)

Try to add before case _ with

case n: String => fibonacci(n.toInt)

to match String type.

Case Class

Case classes are used to conveniently store and match on the contents of a class. You can construct them without using new. It also has hashcode, equality and nice toString methods.

Because of the require(n >= 0), it will throw an exception when the input is negative.

Function Power

This example determines whether there is an odd number in the list using imperative programming.

Try to change

containsOdd(list)

to

list.exists((x: Int) => x % 2 ==1)

Through treating function as arguments, programing can be more simple. It can be even changed to

list.exists(_ % 2 == 1)

_ can be used to replace arguments

Ruby's power is from magic, but Scala's power is from science.

Function True Power

Besides simplifying code, functional programming is more concerned with Input & Output without side-effects.

Like the Unix pipeline, simple commands can be combined together.

If you like the way Unix pipelines commands, you may also like functional programming

This example uses Scala code to simulate the function of

cat file | grep 'warn' | grep '2013' | wc

The first filter function in List accepts a function as an argument, returning a new filtered List as the input to the next function.

Word Count

Word Count is a classic use case for Map Reduce. Map Reduce with functional programming is an intuitive solution to the Word Count problem.

The example shows two important functions 'map' and 'reduceLeft' in List.

The map function accepts a translation expression and returns the translated list.

The reduceLeft function accepts a combining expression and returns the combined result.

Map and ReduceLeft can replace a for-loop expression, making code cleaner.

Tail Recursion

Tail Recursion is one type of Recursion, in which a function calls itself as its last expression. Tail Recursion is very popular in functional programming.

This example shows how to implement foldLeft with Tail Recursion.

Lists can be pattern matched by '::', the first element returned is head, and the others are the tail.

PS: Tail Recursion can be optimized at compile time. So there's no need to worry about stack overflow.

Powerful For Loop

For-Loop is a common feature in imperative programming. Scala improved it to suit functional programming.

For-Loop expressions in Scala can also return a List. With 'yield' in the loop, the value after yield will be appended to the List.

This example replaces the map function with for loop.

Option

Scala provides an Option feature to avoid checking null everywhere.

This example creates a getProperty function, which returns Option instead of null. We don't need to check null, getting a value from Option is enough.

Using pattern matching is a common way to get the value of Option. Use getOrElse() to set a default value when Option is None.

Another important thing is that Option contains lots of functions in List, so it can be used like a list most of time.

Goodbye NullException.

Lazy Initialization

Lazy can lazily initialize value.A field with the lazy keyword is only initialized when it is first accessed.

This example is to get the Scala Version Code from Github. It takes a little time because of network latency. So we can get it with lazy to avoid unnecessary IO blocking.

Lazy is very suitable for the value takes lots of resources.

ConcurrentStart

Content(Concurrent)

Using Actor

Actors are one of Scala's concurrent models. Users of Scala earlier than version 2.10 must install Akka.

An Actor is a like a thread instance with a mailbox. It can be created with system.actorOf: use receive to get a message, and ! to send a message.

This example is an EchoServer which can receive messages then print them.

Simplify Actor

There is a simpler way to define an Actor.

There is the actor function in

akka.actor.ActorDSL

This function accepts an Actor instance, and returns a started Actor.

Actor Implementation

An Actor is more lightweight than a thread. Millions of actors can be generated in Scala, the secret is that an Actor can reuse a thread.

The mapping relationship between an Actor and a Thread is decided by a Dispatcher.

This example creates 4 Actors, and prints its thread name when invoked.

You will find there is no fixed mapping relationship between Actors and Threads. An Actor can use many threads. And a thread can be used by many Actors.

Synchronized Return

Actors are very suitable for long-running operations, like getting resources over a network.

This example creates a Future with the ask function.

In the actor we use 'sender !' to return the value.

Like Option, Future has lots of functions. The result can be printed with a foreach.

Asynchronous Return

Asynchronous operations can provide better performance. A Future in Scala is very powerful, it can execute asynchronously.

The Future will call the 'onComplete' function when it is finished.

It can also set a TIMEOUT when specified.

Parallel Collection

This example prints the time needed to access several URLs. If we access them in parallel, the performance can be better.

Try to change

urls.map

to

urls.par.map

Now, the functions in map will run in parallel.

It's exciting to combine functional and concurrent programming!

Parallel Word Count

Here is the word count example from earlier, improved using a parallel collection.

It can leverage the power of multiple cores without increasing the complexity.

Remote Actor

Actor is not only a concurrency model, it can also be used for distributed computing.

This example builds an EchoServer using an Actor.

Then it creates a client to access the Akka URL.

The usage is the same as with a normal Actor.

PracticeStart

Content(Practice)

Using Java

Scala can execute Java code very easily. There have already been many examples of this.

Java can also use Scala. This example shows how to use the @BeanProperty Annotation to create a Java Style Bean.

Try to change

var name: String

to

@BeanProperty var name: String

Now the bean contains getter/setter functions. And the Apache BeanUtils can work correctly.

Equality

In Scala == is the same as equals function. It's not the same as Java, but it's more reasonable.

Correctly writing an equals function is difficult. This example has an issue with subclasses.

Try to change 'class' to 'case class', and delete the equals function.

Case Class correctly generates the equals function for us.

Extractor

Extractor objects can deconstruct pattern matches.

This example builds an Email Extractor, only the 'unapply function' is needed.

Scala's Regex contains an extractor, which extracts a List. The List elements sequentially match expressions captured in ().

Extractor is very useful. There are 2 cases in this example.

case user :: domain :: Nil

extracts a List.

case Email(user, domain)

extracts an Email object.

Memory Pattern

Memory Pattern can be used to simplify caching.

In this example, the 'memo function' wraps a function without caching to add the simple cache capability.

In this Fibonacci example, a cache improves performance after the first call.

Try to change

fibonacci_(n - 1) + fibonacci_(n - 2)

to

memo(fibonacci_)(n - 1) + memo(fibonacci_)(n - 2)

This improves performance of the first call.

Implicit Conversion

Implicit can be used to define a Conversion function. Types are automatically implicitly converted when needed.

This example converts String to Date automatically. Implicit is the most important feature when implementing a DSL.

DSL

DSL is the most powerful tool in Scala. With it Scala code can become more descriptive.

This example generates Json with a DSL. Some of the features look like native features but are created by a DSL.

It's complex to write your own DSL. But it's very easy to use.

Testing

Scala can use Spec2 or ScalaTest to test, and a DSL can make testing even easier.

This example tests a Factorial function. It creates a test case with should/in.

Test cases run concurrently by default.

Simple Build Tool

SBT is a very popular build tool for Scala.

With its help, you can begin developing Scala without installing anything except the JRE.

If you want to run this Scala Tour in your computer, follow the steps to the left.

About

The Scala Tour is create by the love of Scala and the desire that more people would love it.

Other Resources:

comments powered by Disqus

Use a spacebar or arrow keys to navigate

Designed by Kay Yan,Snack Bandit,Jim Schubert,Christopher Hilla