Scala: From Zero to Algorithms
Introduction
Hi all,
In previous post, I have guided you to prepare the environment, install IDE, and write first Hello World Scala application using IntellJ. If you have not read it, please take a quick look at this link
Today, I will introduce somethings basic of Scala, and solve some basical algorithms using Scala with you guys. I will continue the rests in next some articles.
First, I want to introdue that Scala is functional programming + object oriented programming. How you guys differentiate procedures, methods and functions? Check out my opinion!
– Procedure: A sequence of statements. such as assignments, tests, loops and invocations of sub procedures. These procedures are functions, which map arguments to return statements.
– Method: Something like procedure, however, it is belong to class or object. And can be public, private or protected. It is also can be overloaded. In order to use method, you call via a class or object. However, In my opinion, you cant use methods as parameters, or another type of variables.
– Function: You can google Scala functions, It is also a sequence of statements. However, It much more useful and flexible. You can use functions as other functions parameters, types of variables.
Ok, now what you are going to do is some basic of Scala, ofcourse, including functional programming.
Below are what I summarize from this http://scalatutorials.com/. You can check it out for more details. I just summarize first part of this tutorial in this post. Next parts will be in my next articles.
Basic Scala – part 1
Please read this to the end and practice with the project you have created at previous article by simply typing into it!
- In Scala, primitives are represented as objects. If you are familiar with Ruby, you will understand this (Although after compilation they are using Java’s primitives when possible for performance).Since they are objects, operators are simply method calls!
So 1 + 2 is simply calling a method named + on the object 1 (an Int literal) - Variables are declared using the
var
keyword
In many cases, the type information can be omittedvar x: Int = 1 + 2 var x = 1 + 2 // x = 3
- Final variables are declared using the
val
keyword (a final variable is a variable that can’t be reassigned) - String interpolation
From Scala 2.10, string interpolation is supported.import scala.math._ val Tau = Pi*2 // 6.283185307179586 println(s"Happy $Tau Day")
- Number operations
//Ranges //creates a range between 1 to 10 inclusive val range = 1 to 10 // Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) //creates a range between 1 to 10 exclusive val range2 = 1 until 10 // Range(1, 2, 3, 4, 5, 6, 7, 8, 9) //from 2 to 10 with jumps of 3 val range3 = 2 until 10 by 3 // Range(2, 5, 8)
- String operations
val reverse = "Scala".reverse //reverse a string // "alacS" println(reverse) //alacS val cap = "scala".capitalize //make first char caps // "Scala" println(cap) //Scala val multi = "Scala!" * 7 //repeat n times // "Scala!Scala!Scala!Scala!Scala!Scala!Scala!" println(multi) //Scala!Scala!Scala!Scala!Scala!Scala!Scala! val int = "123".toInt //parse as Int // 123 println(int)
- Useful methods on collections
//filter - keep only items larger than 4 val moreThan4 = range.filter(_ > 4) // Vector(5, 6, 7, 8, 9, 10) println(moreThan4) //Vector(5, 6, 7, 8, 9, 10) //map - transform each item in the collection val doubleIt = range2.map(_ * 2) // Vector(2, 4, 6, 8, 10, 12, 14, 16, 18) println(doubleIt) //Vector(2, 4, 6, 8, 10, 12, 14, 16, 18)
- In Scala methods are defined using def
def add(x:Int, y:Int):Int = { return x + y } println(add(42,13)) //Curly braces are optional on single line blocks def add(x:Int, y:Int) = x + y
- return multiple variables using Tuples
def swap(x:String, y:String) = (y, x) val (a,b) = swap("hello","world") println(a, b)
- Declare and assign multiple variables to the same value.
var x, y, z = 0 var (x, y, z, c, python, java) = (1, 2, 3, true, false, "no!")
- Loops using while
var i, sum = 0 while ( i < 10) { sum += i i+=1 } println(sum)
- Loops using for
var sum = 0 for ( i <- 0 until 10) { sum += i } println(sum)
- Conditions
if (true) println("no braces on a single expression") if (1 + 1 == 2) { println("multiple") println("statements") println("require") println("braces") } else { println("new math is found!") println("or your CPU went crazy") } val likeEggs = false val breakfast = if (likeEggs) "scrambled eggs" else "Apple" println(breakfast)
- Multiple cases
val selection = "One" selection match { case "One" => println("You selected option one!") case "Two" => println("You selected option two!") case _ => println("You selected something else: ") }
- Array
// Mutable array of type Array[Int] // Arrays are constructed simply using Array(element1, element2, ...) // Arrays in Scala map to Java primitive Arrays (e.g. Java's int[] is Scala's Array[Int], Java's String[] is Array[String] in Scala) // Arrays are mutable (can't change it's size once created, but can modify it's elements) // Since they are using Java's arrays, to print nicely an Array's content, use .mkString(",") // Array elements can be of any type, but the Array's final type will be the lowest common denominator def printArray(array:Array[Int]) = println(array.mkString("Array(" , ", " , ")")) //Mutable array of type Array[Int] val array1 = Array(1, 2, 3) // array1 = [I@6ae01647 printArray(array1)// Array(1, 2, 3) //Modify items the same way array3(0) = "d" printArray(array3) // Array(d, b, c) //Concatenation using the ++ operator, //Prepending items using +: and appending using :+ val concatenated = "prepend" +: (array1 ++ array2) :+ "append" // concatenated = [Ljava.lang.Object;@46d0397 printArray(concatenated) // Array(prepend, 1, 2, 3, a, 2, true, append) //Finding an index of an item array3.indexOf("b") // 1
- Functional programming
Example: (You can practice on terminal via command scala)var increase = (x: Int) => x + 1 // increase: Int => Int =
This means: "A function that map from integer (Int) to (=>) an integer (Int)
Call function
increase(10) // res0: Int = 11
Another example of calling anonymous function as parameter. (You can back to your IDE)
//a method that requires a function as a parameter //the function's type is (Int,Int) => Int //e.g. maps from 2 Ints to an Int def doWithOneAndTwo(f: (Int, Int) => Int) = { f(1, 2) } //Explicit type declaration val call1 = doWithOneAndTwo((x: Int, y: Int) => x + y) //The compiler expects 2 ints so x and y types are inferred val call2 = doWithOneAndTwo((x, y) => x + y) //Even more concise syntax val call3 = doWithOneAndTwo(_ + _) println(call1, call2, call3)
Practice
Now, I think it is enough for the first basic part of Scala. And now I want to solve some small problems as practices
The first algorithm I want to solve is the very famous Fibonacci algroithm
def fibonacci( n : Int) : Int = n match { case 0 | 1 => n case _ => fibonacci( n-1 ) + fibonacci( n-2 ) } println ("fibonacci 0: " + (fibonacci(0))) println ("fibonacci 1: " + (fibonacci(1))) println ("fibonacci 2: " + (fibonacci(2))) println ("fibonacci 3: " + (fibonacci(3))) println ("fibonacci 4: " + (fibonacci(4))) println ("fibonacci 5: " + (fibonacci(5)))
The next program should be one of the problem we did together at TDD bootcamp: closedRanged
I want to deploy three functions in this: initialize range, select lower end point, and select upper end point. In each function, we should have a message error if range is not valid. Below are examples functions (ofcourse, at this time, it's not neccessary to refactor these three functions)
var initialize = (lower : Int, upper : Int) => { if (lower { if (lower <= upper){ (lower) } else { ("Invalid Input") } } var UpperEndPoint = (lower : Int, upper : Int) => { if (lower <= upper){ (lower) } else { ("Invalid Input") } } println("initialize range 1-2: " + initialize(1, 2)) println("initialize range 2-1: " + initialize(2, 1)) println("Lower end point of range 1-2: " + lowerEndPoint(1, 2)) println("Upper end point of range 1-2: " + UpperEndPoint(1, 2)) }