2. Programming with Functional Objects inScalaScala is the
perfect mixture of Object Oriented (OO) andFunctional Programming
(FP). You get the flexibility of FPalong with the familiarity of
OO; along with the awesomepower of the Actor model.
3. What is the Functional Object 1- A function in Scala is a
complete object. There are aseries of traits in Scala to represent
functions with variousnumbers of arguments: Function0, Function1,
Function2, etc 2- As an instance of a class that implements one of
thesetraits, a function object has methods3-One of these methods is
the apply method, which containsthe code that implements the body
of the function.4-Scala has special "apply" syntax: if you write a
symbolname followed by an argument list in parentheses (or just
apair of parentheses for an empty argument list), Scalaconverts
that into a call to the apply method for the namedobject.
4. What is the Functional Object5-When we create a variable
whose value is a functionobject and we then reference that variable
followed byparentheses, that gets converted into a call to the
applymethod of the function object.6-When we treat a method as a
function, such as byassigning it to a variable, Scala actually
creates afunction object whose apply method calls the
originalmethod, and that is the object that gets assigned to
thevariable. class test {def m1(x:Int) = x+3 val f1 = (x:Int) =>
x+3}
5. What is the Functional Object Scala has both functions and
methods and we use theterms method and function interchangeably
with a minordifference.# A Scala method is a part of a class which
has a name, asignature, optionally some annotations, and some
bytecodewhere as a function in Scala is a complete object which
canbe assigned to a variable. # In other words, a function which is
defined as a member ofsome object is called a method.
6. Scala is a functional language, in the sense that every
function is a Value. Iffunctions are values, and values are
objects, it follows that functionsthemselves are objects. The
function type S => T is equivalent toscala.Function1[S, T] where
Function1 is defined
as------------------------------------------------------------------------------------------------------trait
Function1[-S, +T] {def apply(x: S): T}So functions are interpreted
as objects with apply methods.For example, theanonymous successor
function (x: Int ) => x + 1 is expanded
to--------------------------------------------------------------------------------------------------------new
Function1[Int, Int] {def apply(x: Int): Int =x+1
7. Function Declarations:A scala function declaration has the
following form:def functionName ([list of parameters]) : [return
type]Function Definitions:A scala function definition has the
following form:def functionName ([list of parameters]) : [return
type] = {function bodyreturn [expr]}
8. Function ImplementationA function which does not return
anything canreturn Unit which is equivalent to void in Java
andindicates that function does not return anything.The functions
which do not return anything inScala, they are called procedures.
Following is thesyntaxobject Hello{ def printMe( ) : Unit = {
9. Calling Functions:Scala provides a number of syntactic
variations forinvoking methods. Following is the standard way to
calla method:functionName( list of parameters )If function is being
called using an instance of theobject then we would use dot
notation similar to Javaas follows:[instance.]functionName( list
of
10. Fun With Scala Functionsscala> def method1() ={
println("method1") }method1: ()Unitscala> def method2(str:
String) ={ println("method2: " + str) }method2:
(String)Unitscala> def method3(str: String): Int = {
11. Fun With Scala Functionsscala> method1method1scala>
method2("abc")method2: abcscala> method3("abcdefg")
12. Fun With Scala Functions* When we type def method1() = {}
we actuallydeclared an instance of a special class. Ill declare
method1again, but with the underlying object exposed:scala> val
method1 = new Function0[Unit] { | def apply: Unit = {
println("method1") } |}method1: java.lang.Object with () => Unit
= scala> method1res1: java.lang.Object with () => Unit =
scala> method1.applymethod1scala> method1()
13. #We instantiate an instance of traitFunction0[Unit] and
implement its oneabstract method, called apply, and assignit to a
val named method1. Now you cansee method1 is actually just a plain
oldScala object. When we type in method1and hit enter, the
interpreter just tells usthe resulting value of the statement
whichis an Object with trait Function0. Hmm,that didnt work. Next
we try calling theapply method on the object.
14. That Function0[Unit], by the way, defines afunction that
takes 0 parameters and returns Unit(which is to say nothing as in
Java void (not to beconfused with Nothing)). If you want a
functionthat takes two parameters, an Int and a String,and returns
a List of Doubles, you would useFunction2[Int, String,
List[Double]]. So classFunctionX takes (X+1) type parameters, the
firstX of which define the function parameter types,and the last of
which defines the return type.
15. scala> def method2 = { println("method2") }method2:
Unitscala> val m2: () => Unit = method2:5: error: type
mismatch;found : Unitrequired: () => Unitval m2: () => Unit =
method2^scala> def method2() = { println("method2") }method2:
()Unit
16. # First we just define a function called method2. Nothing
fancy. Thenwe try to assign it to a val of type () => Unit. It
fails. See the errormessage? Found : Unit. It parses it all wrong.
Scala thinks weretrying to call method2 and assign the result to
m2. How can we setthings straight? Well, one way is to slightly
change the way we definemethod2. The only difference in the first
and second definition is theaddition of an empty parameter list,
that empty pair parentheses. # For some reason, when we define the
method in this apparentlyequivalent fashion, Scala rightly
interprets our intentions and allows usto assign to m2. There is
another way, though. In the third definition ofmethod2, weve again
removed the parentheses. But this time weassign it successfully to
val m2 by following method2 with anunderscore. The underscore just
causes Scala to treat method2 as aFunction0 object, rather than
attempting to invoke it.
17. Fun With Scala Functions 1-We instantiate an instance of
traitFunction0[Unit] and implement its one abstractmethod, called
apply, and assign it to a valnamed method1.2-Now you can see
method1 is actually just aplain old Scala object. When we type
inmethod1 and hit enter, the interpreter just tellsus the resulting
value of the statement which isan Object with trait Function0. Hmm,
that didntwork.
18. Fun With Scala FunctionsIf you want a function that takes
two parameters,an Int and a String, and returns a List of
Doubles,you would use Function2[Int, String,List[Double]]. So class
FunctionX takes (X+1)type parameters, the first X of which define
thefunction parameter types, and the last of whichdefines the
return type.
19. How can we use traitstrait Function3[-T1, -T2, -T3, +R]
extends AnyRef{...def apply( v1 :T1, v2 :T2, v3 :T3 ) : R...}
20. Fun With Scala Functionsscala> def method2 = {
println("method2") }method2: Unitscala> val m2: () => Unit =
method2:5: error: type mismatch;found : Unitrequired: () =>
Unitval m2: () => Unit = method2 ^* we just define a function
called method2.
21. Fun With Scala Functions1-The only difference in the first
and seconddefinition is the addition of an empty parameterlist,
that empty pair parentheses. For somereason, when we define the
method in thisapparently equivalent fashion, Scala
rightlyinterprets our intentions and allows us to assignto m2.2- In
the third definition of method2, weve againremoved the parentheses.
But this time weassign it successfully to val m2 by following
22. Scala - Functions Call-by-NameA call-by-name mechanism
passes a code block to the callee and each time thecallee accesses
the parameter, the code block is executed and the value
iscalculated.
24. Scala - Function with Variable ArgumentsScala allows you to
indicate that the last parameter to afunction may be repeated. This
allows clients to passvariable length argument lists to the
function. Following is asimple example to show the concept.
25. Function with Variable Argumentsobject Test {def main(args:
Array[String]) {printStrings("Hello", "Scala", "Python");}def
printStrings( args:String* ) = {var i : Int = 0;for( arg
x*yVariable mul is now a function that can be used the
40. Scala - Currying FunctionsCurrying transforms a function
that takes multipleparameters into a chain of functions, each
takinga single parameter. Curried functions are definedwith
multiple parameter lists, as follows:def strcat(s1: String)(s2:
String) = s1 + s2Alternatively, you can also use the
followingsyntax to define a curried function:
42. Scala - ClosuresA closure is a function whose return value
depends onthe value of one or more variables declared outsidethis
function. Consider the following piece of code withanonymous
function:val multiplier = (i:Int) => i * 10Here the only
variable used in the function body, i * 0,is i, which is defined as
a parameter to the function.Now let us take another piece of
code:val multiplier = (i:Int) => i * factorThere are two free
variables in multiplier: i and factor.One of them, i, is a formal
parameter to the function.
43. Scala - Closuresobject Test {def main(args: Array[String])
{println( "muliplier(1) value = " + multiplier(1) )println(
"muliplier(2) value = " + multiplier(2) )}var factor = 3val
multiplier = (i:Int) => i * factor}Above function references
factor and reads its current value each time. If a
44. PROBLEMclass TestClass { | def f1(): Unit = {
println("f1!!!"); func = f2 } | def f2(): Unit = {
println("f2!!!"); func = f3 } | def f3(): Unit = {
println("f3!!!"); func = f1 } | | var func: () => Unit = f1 | |
def test = { func() } |}IF tc is the object of the class than
output ofscala> tc.test, scala> tc.test and scala>
tc.test