Page Contents
What is Scala Function ?
Scala supports functional programming approach. It provides rich set of built-in functions and allows you to create user defined functions also.In Scala, functions are first class values. You can store function value, pass function as an argument and return function as a value from other function. You can create function by using def keyword. You must mention return type of parameters while defining function and return type of a function is optional. If you don’t specify return type of a function, default return type is Unit.
Scala has both functions and methods and we use the terms method and function interchangeably with a minor difference. A Scala method is a part of a class which has a name, a signature, optionally some annotations, and some bytecode where as a function in Scala is a complete object which can be assigned to a variable. In other words, a function, which is defined as a member of some object, is called a method.
NOTE: Scala function’s name can have characters like +, ++, ~, &,-, –, \, /, :, etc.
Function Declarations
def functionName ([list of parameters]) : [return type]
Methods are implicitly declared abstract if you don’t use the equals sign and the method body.
Function Definitions
Syntax
def functionName ([list of parameters]) : [return type] = {
function body
return [expr]
}
NOTE :
- “return” keyword is not mandatory.
- Return type is only mandatory for a recursive function.
Here, return type could be any valid Scala data type and list of parameters will be a list of variables separated by comma and list of parameters and return type are optional. Very similar to Java, a return statement can be used along with an expression in case function returns a value.
Example – Function to add two numbers.
object Test {
def addInt( a:Int, b:Int ) : Int = {
a + b
}
}
Example – Function returning Unit
Unit return type is used for a function that does not return anything. Unit is equivalent to void in Java.
A function which does not return anything is called a Procedure.
Here is the syntax −
object Hello{
def printMe( ) : Unit = {
println("Hello, Scala!")
}
}
How to call a function ?
Scala provides a number of syntactic variations for invoking methods. Following is the standard way to call a method −
functionName( list of parameters )
If a function is being called using an instance of the object, then we would use dot notation similar to Java as follows −
[instance.]functionName( list of parameters )
Example
object Demo extends App {
def main(args: Array[String]) {
println( "The sum is: " + addInt(5,5) );
}
def addInt( a:Int, b:Int ) : Int = {
a + b
}
}
Output
Returned Value : 10
Some Function examples
Example – Recursive function
The process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called as recursive function.
object Demo extends App {
def main(args: Array[String]) {
println( "Factorial of 4 is: " + fact(4) );
}
def fact(x: Int): Int = {
if (x == 0) 1 else fact(x - 1)
}
}
Output
24
Higher Order Functions
Higher order functions take other functions as parameters or return a function as a result. This is possible because functions are first-class values in Scala.
One of the most common examples is the higher-order function map which is available for collections in Scala.
Example
val sal= Seq(100, 200, 300) val doubleSalary = (x: Int) => x * 2 val salNew= sal.map(doubleSalary)
Output
List(200, 400, 600)
Coercing methods into functions
It is also possible to pass methods as arguments to higher-order functions because the Scala compiler will coerce the method into a function.
Example
object MethodCoercing extends App {
val x = new ConvertTemperature(List(100.0,101.1,102.3))
println(x.forecastInFahrenheit)
}
class ConvertTemperature(temperatures: List[Double]){
private def convertCtoF(temp: Double) = temp * 1.8 + 32
def forecastInFahrenheit: Seq[Double] = temperatures.map(convertCtoF)
}
Output
List(212.0, 213.98, 216.14)
Explanation : In the above example, the method convertCtoF is passed to the higher order function map. This is possible because the compiler coerces convertCtoF to the function e => convertCtoF(e) ( Note:e will be a generated name which is guaranteed to be unique within its scope ).
Functions that accept functions
Higher-order functions reduce redundant code. Lets say we want to create a function that calculates sum of int values from a to b or sum of cubes from a to b, we can write a code as mentioned below
object Test extends App {
def sumInts(a: Int, b: Int): Int = {
if (a > b) 0 else a + sumInts(a + 1, b)
}
def sumCubes(a: Int, b: Int): Int = {
if (a > b) 0 else cube(a) + sumCubes(a + 1, b)
}
def cube(x: Int): Int = { x * x * x }
println(sumInts(3, 5))
println(sumCubes(3, 5))
}
We can write the same code using a higher-order function
object HigherOrderFuncExample extends App {
def sum(f: Int => Int, a: Int, b: Int): Int = {
if (a > b) {
return 0
} else {
return f(a) + sum(f, a + 1, b)
}
}
// Calculating Sum of Cubes using the higher-order function.
def sumCube(a: Int, b: Int) = { sum(n => n * n * n, a, b) }
println(sumCube(1, 3))
// Calculating Sum of Ints using the higher-order function.
def sumInts(a: Int, b: Int) = { sum(n => n, a, b) }
println(sumInts(1, 3))
// Calculating Sum of factorials using the higher-order function.
def fact(x: Int): Int = {
if (x == 0) 1 else fact(x - 1)
}
def sumFact(a: Int, b: Int) = { sum(fact, a, b) }
println(sumFact(1, 3))
}
Output
36
6
3
In the above example, the function sum is a higher order function. The first argument is a function itself ( f: Int => Int). The same function can calculate sum of Int, sum of Cubes etc.
Functions that return functions
We can also write a function that can return a function.
Example
object FuncReturningFunc extends App {
def urlBuilder(ssl: Boolean, dom: String): (String, String) => String = {
val schema = if (ssl) { "https://" } else { "http://" }
// Returning a function
(endpoint: String, query: String) => s"$schema$dom"
}
val domain = "www.proedu.co"
def getURL = urlBuilder(true, domain)
val endpoint = "user"
val query = "id=1001"
val url = getURL(endpoint, query)
println(url)
}
