Function
Scala function's name can have characters like +, ++, ~, &,-, --, \, /, :, etc.
def functionName ([list of parameters]) : [return type] = {
function body
return [expr]
}
import scala.util.Random
object Demo
{
// return an random integer
def getNum() : Int = {
var r = new Random();
return r.nextInt(10);
}
// no return
def hello() : Unit = {
println("Hello World!");
}
def main(args : Array[String])
{
println(getNum());
hello();
}
}
Call by Value and Call by Name
object Demo
{
def doSomething() : Int = {
println("Do something ...");
return 1;
}
// call by value
def callByValue(x : Int) : Unit = {
println(x);
println(x);
}
// call by name
def callByName(x : => Int) : Unit = {
println(x);
println(x);
}
def main(args : Array[String])
{
// pass an integer number, they have the same performance
callByValue(10);
callByName(10);
//call by value
println("Call by value ...");
//>>Do something ...
//>>1
//>>1
callByValue(doSomething());
//call by name
println("Call by name ...");
//>>Do something ...
//>>1
//>>Do something ...
//>>1
callByName(doSomething());
}
}
Variable Arguments
object Demo
{
def getArgs(num : Int, args : String*)
{
println("Total %d parameters ...".format(num));
for(arg <- args)
println(arg)
}
def main(args: Array[String])
{
getArgs(4, "p1", "p2", "p3", "p4");
}
}
Default Parameter Values
object Demo
{
def getSum(a : Int = 1, b : Int = 10) : Int =
{
return a + b
}
def main(args : Array[String])
{
// not use default value
println(getSum(1, 2));
// pass value to a, b use the default value
println(getSum(1));
// a use the default value, assign value to b
println(getSum(b=2));
}
}
Nested Functions
object Demo
{
def factorial(i : Int) : Int = {
def fact(i: Int, accumulator: Int): Int = {
if (i <= 1)
accumulator
else
fact(i - 1, i * accumulator)
}
return fact(i, 1)
}
def main(args : Array[String])
{
println(factorial(4));
}
}
Partially Applied Functions
object Demo
{
def getSum(a : Int, b : Int) : Int = {
return a+b;
}
def main(args : Array[String])
{
var partialSum = getSum(1, _ : Int);
println(partialSum(10));
}
}
Named Arguments
object Demo
{
def getSum(a : Int = 1, b : Int = 2) : Int = {
return a+b;
}
def main(args : Array[String])
{
println(getSum(b = 10, a = 100));
}
}
Recursion Functions
object Demo
{
def factorial(n : Int) : Int = {
if( n <= 1)
return 1
else
return n*factorial(n-1)
}
def main(args : Array[String])
{
println(factorial(4));
}
}
Higher-Order Functions
Functions can take other functions as parameters, or whose result is a function
object Demo {
def main(args: Array[String]) {
println( apply( layout, 10) )
}
def apply(f: Int => String, v: Int) = f(v)
def layout[A](x: A) = "[" + x.toString() + "]" // A is parameter type
}
object Demo {
def main(args: Array[String]) {
println( apply(getSum, 10) )
}
def getSum(a : Int, b : Int) : Int = {
return a+b;
}
def apply(f: (Int, Int) => Int, v: Int) = f(v, v)
}
Anonymous Functions
object Demo
{
def main(args : Array[String])
{
var getSum = (a:Int, b:Int) => a+b;
println(getSum(10, 100));
}
}
Currying Functions
Currying transforms a function that takes multiple parameters into a chain of functions, each taking a single parameter
object Demo
{
def doubleNum(a : Int) : Int = 2*a;
def getSum(a: Int)(b : Int) : Int = {
return doubleNum(a) + doubleNum(b)
}
def main(args : Array[String])
{
println(getSum(10)(100));
}
}
Reference