Uncategorized

Functions and Closures

  • Local functions: in Scala, you can define functions inside other functions. They will be inaccessible from outside the containing method. They can access the parameters of their enclosing functions
  • Function literals:
var increase = (x: Int) => x + 1
increase(10) //prints 11
  • foreach method takes a function as an argument and invokes that function on each of its elements:
val myList = List (1, 2, 3)
myList.foreach((x: Int) =>  (x))
  • filter method selects those elements of the collection that pass a test the user supplies:
val myList = List (1, 2, 3)
println(myList.filter((x: Int) => x > 2)) //prints 3
//or mix them with foreach:
myList.filter((x: Int) => x > 2).foreach((x: Int) => println(x)) //prints 3
  • One way to make function literals more brief, is to leave off the parameter types. This is called target typing because the targeted usage of an expression is allowed to influence the typing of that expression:
println(myList.filter((x) => x > 2)) // same as x => x > 2
  • Placeholder syntax: you can use underscores as placeholders for one or more parameters, as long as each parameter appears only one time within the function literal. Multiple underscores mean multiple parameters, not reuse of a single parameter repeatedly:
myList.filter(_ > 2)
  • Partially applied function: is an expression in which you don’t supply all of the arguments needed by the function. Instead, you supply some, or none of the needed arguments. You can replace an entire parameter list with an underscore:
//e.g.1:
myList.foreach((x: Int) => println(x)) //is same as:
myList.foreach(println _) //is same as:
myList.foreach(println)

//e.g.2:
def sum(a: Int, b:Int, c: Int) = a + b + c
val a = sum _
a(1, 2, 3) // 6
val b = sum(1, _ : Int, 3)
b(3) // 7
  • Closures: closures capture variables themselves, not the value to which the variables refer:
val more = 10
val addMore = (x: Int) => x + more //more is called a free variable, x is bounded variable
  • Special function call forms: Scala supports repeated parameters, named arguments, and default arguments:
    • Repeated parameters: Scala allows you to indicate last parameter of a function may be repeated:
def echo(args: String*) = 
    for(arg <- args) println (arg)

echo(“Hello”, “world”)

//you can pass an array of strings to this method this way:
val strArr = Array(“Hello”, “World”)
echo(strArr: _*) //this tells the compiler to pass each element of array as its own argument to echo, rather than all of it as one single argument
    • Named arguments: named arguments allow you to pass arguments to a function in a different order:
def speed(distance: Float, time: Float): Float = distance / time
speed(time = 10, distance = 100)
    • Default parameter values: Scala lets you specify default values for function parameters
def speed(distance: Float, time: Float = 50): Float = distance / time
speed(distance = 100) //2
  • Tail recursion: functions which call themselves as the last action, are called tail recursive. The Scala compiler detects tail recursion and replaces it with a jump back to the beginning of the function, after updating the function parameters with the new values. So, if the method is tail recursive, there won’t be any runtime overhead to be paid:
def approximate(guess: Double): Double = {
    if (isGoodEnough(guess)) guess
    else approximate(improve(guess))
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s