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
  • Tutorialspoint