This post originated from an RSS feed registered with Scala Buzz
by Zemian Deng.
Original Post: Scala methods, functions and closure
Feed Title: thebugslayer
Feed URL: http://www.jroller.com/thebugslayer/feed/entries/atom?cat=%2FScala+Programming
Feed Description: Notes on Scala and Sweet web framework
In the following exercise code, I will show some typical Scala methods and functions declarations and usages.
First of all, there doesn't seem to be much distinction between Scala's function and closure. A closure in Scala is a function. A function in Scala is an object that can store a block of codes and is invokable. Of course a function can also declared to accept parameters as well. You may store function into a variable, and invoke it as many times as you wish, and you may pass it to other functions or methods as parameter just as all other objects created in the program.
A method in Scala is not an object, but just a block of codes that can be invoked. As result, you may not pass a defined method into another function/method. A method is used to define member of a Class.
As you will see from code below that you CAN mix usage of function as parameter in a method, and that's where some power features of Scala comes into play.
var index = 0
var result = 0
//===> Regular method declarations and usages.
//define a method
def m() : Int = { index +=1; index }
// using the method
println(m()) // => 1
println(m) // => 2 Notice that it can be invoked without parenthesis!
// same as above but with inferred return type
def m2() = { index +=1; index }
println(m2) // => 3
println(m2()) // => 4
// similar as above but even shorter, without param parenthesis!
def m3 = { index +=1; index }
println(m3) // => 5
//println(m3()) // ERROR! you can't invoke it with parenthesis now!
Above are some normal way to declare methods that contains no parameters. Now let's see some function/closure in actions.
//===> Closure/Function as object/variable
// creating a closure as object and store it into a variable
// var_name closure parameters
// | | closure block
val closure = () => { index +=1; index }
// using the closure
println(closure()) // => 6 Invoking closure with parenthesis
println(closure) // => <function> Not invoking closure, but to pass in as an object!
println(closure.toString) // => <function> Just like above line, use it as object.
//===> Closure/Function as method parameter
// notice that you DECLARE the closure TYPE, not creating it in this step!
def m3(cParam : () => Int) = cParam()
// now use m3 by creating a closure object on the fly
result = m3(() => { index +=1; index })
println(result) // => 7
//use m3 by pass in a previously saved closure object
result = m3(closure)
println(result) // => 8
Above are most common way to define and declare closure in Scala. Notice that even your closure has no parameter, you still need to create the closure with "() =>" because that's the syntax construct. There is a special declaration just for empty parameter closure/function that you may use to gain some even shorter syntax. Scala calls this By-Name function.
//===> Closure/Function as method parameter without parenthesis, (also called by-name function/method)
// Notice that no parenthesis are used when declaring this closure/function TYPE.
def byName(func : => Int) : Int = func
//To pass code into by-name method, you create just the code block instead. no paren, not even '=>' are needed.
result = byName({ index +=1; index })
println(result) // => 9
//parenthesis can be omitted on the method if that's the one/last parameter!
result = byName{ index +=1; index }
println(result) // => 10
//Note that you can't pass a normal(previously saved) closure object to a by-name function.
//result = byName(closure) // Error!
//result = byName(() => { index +=1; index }) // Error! Obviously, not on the fly either.
Notice the usage of byName{ index +=1; index }. This special by-name function syntax gives you a very nice looking "User Control" like method invocation, and most importantly, the "control", or byName in this case, is defined by YOU! If your code block are longer, you will see something very conventional like:
myControlMethod{
//execute line one
//execute line two
// ...
}
This is what Scala can give you to extends it's language and "control" like syntax that using your own libraries!