`

scala - function and closures

阅读更多

In this example, we are going to examine the function and closures and here is the outline.

 

 

1. Function

1.1. one thing about Scala is that 

1.2 first class function

1.3 function can be short-forms

1.4 placeholder syntax

2. closure

2.1.  closure in simple form 

3. function call in special form 

3.1 repeated parameters

3.2 Default parameter values 

4. tail recursion 

4.1 an interest note on the tail-recursion limit

 

 

// function_closures.scala

// scala functions and closures in example 

// 1. Function
//
// 1.1. one thing about Scala is that 
//   one strong suite about scala is that you can define local function for Scala

import scala.io.Source

object LongLines {
  def processFile(fileName : String, width : Int) = {
    
    // local function
    def processLine(line : String) = {
      if (line.length > width) println(fileName + ": " + line)
    }
    
    for (line <- Source.fromFile(fileName).getLines) 
      processLine(line)
  }
  
}
// runner 
LongLines.processFile("C:\\dev\\workspace\\scala-train\\src\\functionsAndClosures\\function_closures.scala", 6)

// 1.2 first class function
// function as the first class type means 
//  1). you can create a function literal, which when is compiled into a class that when instantiated at runtime is a function value
//  2). you can pass around the function value around
(x :Int) => x + 1

var increase = (x :Int) => x + 1


val someNumbers = List(-11, -10, -5, 0, 5, 10)

someNumbers.foreach((x :Int) => println(x))

// 1.3 function can be short-forms
// longer form 
someNumbers.filter((x :Int) => x > 0)
// short form
someNumbers.filter(x => x > 0)

//1.4 placeholder syntax
// why do we need 'x', since we barely need that variable name, we can ignore the
// 'x' and the parameter part , and just use following functional body literal
someNumbers.filter(_ > 0)

val f = ( _ : Int) + (_ : Int) 

f(5, 10)

//1.4 partially function

def sum(a :Int, b : Int, c :Int) = a + b  + c

// you can use '_' to create a partially apply function by which you supply none of the required arguments

val a = sum _
a (1 ,2, 3 )
// above is interchanable to the following
a.apply(1, 2, 3)


val b = sum (1, _ :Int, 3)

b(2)

someNumbers.foreach(println _)

// if you are writing a partially function in which you leave off all the parameters, such as println _, or sum _, you can express more concisely by leaving 
// off the underscore if a function is required at that point in the code 
someNumbers.foreach(println)

//NOTE: you cannot do that if data is required... 



//2. closure
// closure is the abilty from within a scope (a local functional literal) which refers to some free local variable, and because of that 
// the lifetime of the freevar has been extended with the local/anonymous function


// 2.1.  closure in simple form 

var more = 1

val addMore = (x : Int) => x + more 

addMore(1)
more = 9999

addMore(10)

// 
def makeIncreaser(more : Int) = (x: Int) => x + more  

val increaser1 = makeIncreaser(1)

val increaser2 = makeIncreaser(2) 

// each time makeIncreaser is called, a new closure is created 
increaser1 == increaser2

// 3. function call in special form 
// 3.1 repeated parameters
def echo(args : String*) = for (arg <- args) println(arg)



echo()
echo("one")
// actually Array[String] will be passed in to the function below  
echo("hello", "world")

// how do we unpack a array, list and pass that as repeated parameters? 
// the key lies in "_*" 
val arr = Array("what's", "is", "up")

echo(arr : _*)


// 3.2 Default parameter values 
// you can pass in default parameter values
def printTime(out : java.io.PrintStream = Console.out) = out.println("Time = " +  System.currentTimeMillis())

// you can call function with default argument values
// with the named arguments (which is called keyword argument in Python) 
def printTime2(out : java.io.PrintStream = Console.out, divisor: Int = 1) = out.println("Time = " +  System.currentTimeMillis() / divisor)

printTime2(divisor = 2)


// 3. tail recursion 
// tail recursion is an  optimization that is performed by the compiler, it just jump back to the beginning of the function 
// with parameter values replaced..

// a non-tail recursive function
def boom(x :Int) : Int = 
  if (x == 0) throw new Exception("boom!")
  else boom(x - 1 ) + 1
// check the stack   
boom(2)  

// a tail recursive one 
def boom(x :Int) : Int = 
  if (x == 0) throw new Exception("boom!")
  else boom(x - 1 )

boom(10)
  
// 3.1 an interest note on the tail-recursion limit
//
// this do not do tail-recursion
def isEven(x : Int) : Boolean = if (x == 0) true else isOdd(x - 1)
def isOdd(x : Int) : Boolean = if (x == 0) false else isEven(x - 1)

isEven(9)

val funValue = nestedFun _
def nestedFun (x : Int) {
  if (x != 0) { println(x); funValue(x - 1)}
}

funValue(3)

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics