SlideShare a Scribd company logo
1 of 45
Download to read offline
Functional Objects
          &
Function and Closures
   < Sandip Kumar > sandip@knoldus.com
Programming with Functional Objects in
                Scala
Scala is the perfect mixture of Object Oriented (OO) and
Functional Programming (FP). You get the flexibility of FP
along with the familiarity of OO; along with the awesome
                power of the Actor model.
What is the Functional Object

 1- A function in Scala is a complete object. There are a
series of traits in Scala to represent functions with various
numbers of arguments: Function0, Function1, Function2, etc
 2- As an instance of a class that implements one of these
traits, a function object has methods
3-One of these methods is the apply method, which contains
the code that implements the body of the function.
4-Scala has special "apply" syntax: if you write a symbol
name followed by an argument list in parentheses (or just a
pair of parentheses for an empty argument list), Scala
converts that into a call to the apply method for the named
object.
What is the Functional Object
5-When we create a variable whose value is a function
  object and we then reference that variable followed by
  parentheses, that gets converted into a call to the apply
  method of the function object.
6-When we treat a method as a function, such as by
  assigning it to a variable, Scala actually creates a
  function object whose apply method calls the original
  method, and that is the object that gets assigned to the
  variable.
   class test {
def m1(x:Int) = x+3
 val f1 = (x:Int) => x+3
        }
What is the Functional Object

 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.
Scala is a functional language, in the sense that every function is a Value. If
functions are values, and values are objects, it follows that functions
themselves are objects. The function type S => T is equivalent to
scala.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, the
anonymous successor function (x: Int ) => x + 1 is expanded to
--------------------------------------------------------------------------------------------------------
new Function1[Int, Int] {
def apply(x: Int): Int =
x+1
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 body
    return [expr]
}
Function Implementation

A function which does not return anything can
return Unit which is equivalent to void in Java and
indicates that function does not return anything.
The functions which do not return anything in
Scala, they are called procedures. Following is the
syntax


object Hello{
 def printMe( ) : Unit = {
Calling Functions:

Scala provides a number of syntactic variations for
invoking methods. Following is the standard way to call
a method:


functionName( list of parameters )

If 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
Fun With Scala Functions
scala> def method1() =
{ println("method1") }
method1: ()Unit


scala> def method2(str: String) =
{ println("method2: " + str) }
method2: (String)Unit


scala> def method3(str: String): Int = {
Fun With Scala Functions

scala> method1
method1


scala> method2("abc")
method2: abc


scala> method3("abcdefg")
Fun With Scala Functions
  * When we type “def method1() = {…}” we actually
declared an instance of a special class. I’ll declare method1
again, but with the underlying object exposed:
scala> val method1 = new Function0[Unit] {
   | def apply: Unit = { println("method1") }
   |}
method1: java.lang.Object with () => Unit = <function>
scala> method1
res1: java.lang.Object with () => Unit = <function>
scala> method1.apply
method1
scala> method1()
method1
#We instantiate an instance of trait
Function0[Unit] and implement its one abstract
method, called apply, and assign it to a val
named method1. Now you can see method1 is
actually just a plain old Scala object. When we
type in “method1″ and hit enter, the interpreter
just tells us the resulting value of the statement
which is an Object with trait Function0. Hmm,
that didn’t work. Next we try calling the apply
method on the object.
#But it’s just a regular call to a member method.
But when we type “method1()” then Scala knows
that we want to use this object as a function, and
that we’re not refering to the object itself. When
you declare a function using “def” Scala assumes
That Function0[Unit], by the way, defines a
function that takes 0 parameters and returns Unit
(which is to say nothing as in Java void (not to be
confused with Nothing)). If 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 the function parameter types,
and the last of which defines the return type.
scala> def method2 = { println("method2") }
method2: Unit
scala> val m2: () => Unit = method2
<console>:5: error: type mismatch;
found : Unit
required: () => Unit
    val m2: () => Unit = method2
                  ^
scala> def method2() = { println("method2") }
method2: ()Unit
# First we just define a function called method2. Nothing fancy. Then
we try to assign it to a val of type () => Unit. It fails. See the error
message? Found : Unit. It parses it all wrong. Scala thinks we’re
trying to call method2 and assign the result to m2. How can we set
things straight? Well, one way is to slightly change the way we define
method2. The only difference in the first and second definition is the
addition of an empty parameter list, that empty pair parentheses.


 # For some reason, when we define the method in this apparently
equivalent fashion, Scala rightly interprets our intentions and allows us
to assign to m2. There is another way, though. In the third definition of
method2, we’ve again removed the parentheses. But this time we
assign it successfully to val m2 by following method2 with an
underscore. The underscore just causes Scala to treat method2 as a
Function0 object, rather than attempting to invoke it.
Fun With Scala Functions
 1-We instantiate an instance of trait
Function0[Unit] and implement its one abstract
method, called apply, and assign it to a val
named method1.


2-Now you can see method1 is actually just a
plain old Scala object. When we type in
“method1″ and hit enter, the interpreter just tells
us the resulting value of the statement which is
an Object with trait Function0. Hmm, that didn’t
work.
Fun With Scala Functions


If 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 the
function parameter types, and the last of which
defines the return type.
trait Function3[-T1, -T2, -T3, +R] extends AnyRef
{
    ...
    def apply( v1 :T1, v2 :T2, v3 :T3 ) : R
    ...
}
Fun With Scala Functions
scala> def method2 = { println("method2") }
method2: Unit
scala> val m2: () => Unit = method2
<console>:5: error: type mismatch;
found : Unit
required: () => Unit
    val m2: () => Unit = method2
                 ^
* we just define a function called method2.
Fun With Scala Functions
1-The only difference in the first and second
definition is the addition of an empty parameter
list, that empty pair parentheses. For some
reason, when we define the method in this
apparently equivalent fashion, Scala rightly
interprets our intentions and allows us to assign
to m2.
2- In the third definition of method2, we’ve again
removed the parentheses. But this time we
assign it successfully to val m2 by following
method2 with an underscore. The underscore
just causes Scala to treat method2 as a
Scala - Functions Call-by-Name

A call-by-name mechanism passes a code block to the callee and each time the
callee accesses the parameter, the code block is executed and the value is
calculated.
Functions
Call-by-Name
object Test {
 def main(args: Array[String]) {
     delayed(time());
 }

 def time() = {
Scala - Function with Variable Arguments

Scala allows you to indicate that the last parameter to a
function may be repeated. This allows clients to pass
variable length argument lists to the function. Following is a
simple example to show the concept.
Function with Variable Arguments
object Test {
  def main(args: Array[String]) {
          printStrings("Hello", "Scala", "Python");
  }
  def printStrings( args:String* ) = {
      var i : Int = 0;
      for( arg <- args ){
          println("Arg value[" + i + "] = " + arg );
          i = i + 1;
      }
Scala - Default Parameter Values for a Function

Scala lets you specify default values for function parameters. The
argument for such a parameter can optionally be omitted from a
function call, in which case the corresponding argument will be
filled in with the default. Following is an example of specifiying
default parameters:
Default Parameter Values for a Function
  object Test {
      def main(args: Array[String]) {
           println( "Returned Value : " + addInt() );
      }
      def addInt( a:Int=5, b:Int=7 ) : Int = {
          var sum:Int = 0
          sum = a + b


          return sum
      }
  }
Scala - Nested Functions

Scala allows you to define functions inside a
 function and functions defined inside other
 functions are called local functions. Here is
 an implementation of a factorial calculator,
 where we use a conventional technique of
 calling a second, nested method to do the
 work
Scala - Nested Functions
   object Test {
       def main(args: Array[String]) {
           println( factorial(0)
           println( factorial(1) )
           println( factorial(2) )
           println( factorial(3) )
       }
   def factorial(i: Int): Int = {
           def fact(i: Int, accumulator: Int): Int = {
              if (i <= 1)
                accumulator
              else
                fact(i - 1, i * accumulator)
   }
           fact(i, 1)}}
Scala - Partially Applied Functions


When you invoke a function, you're said to be applying the
function to the arguments. If you pass all the expected arguments,
you have fully applied it. If you send only a few arguments, then
you get back a partially applied function. This gives you the
convenience of binding some arguments and leaving the rest to
be filled in later. Following is a simple example to show the
concept:
Scala - Partially Applied Functions

import java.util.Date


object Test {
  def main(args: Array[String]) {
      val date = new Date
      log(date, "message1" )
      log(date, "message2" )
      log(date, "message3" )
  }
Scala - Partially Applied Functions

*Here the log( ) method takes two parameters: date and
  message. We want to invoke the method multiple times,
  with the same value for date but different values for
  message. We can eliminate the noise of passing the
  date to each call by partially applying that argument to
  the log( ) method. To do so,
# we first bind a value to the date parameter and leave
  the second parameter unbound by putting an
  underscore at its place. The result is a partially applied
  function that we've stored in a variable.
Scala - Functions with Named Arguments

 Named arguments allow you to pass arguments to a
  function in a different order. The syntax is simply that
  each argument is preceded by a parameter name and
  an equals sign. Following is a simple example to show
  the concept:
Functions with Named Arguments
object Test {
    def main(args: Array[String]) {
         printInt(b=5, a=7);
    }
    def printInt( a:Int, b:Int ) = {
        println("Value of a : " + a );
        println("Value of b : " + b );
    }
}
Scala - Recursion Functions
object Test {
  def main(args: Array[String]) {
      for (i <- 1 to 10)
        println( "Factorial of " + i + ": = " + factorial(i) )
  }


 def factorial(n: BigInt): BigInt = {
      if (n <= 1)
        1
      else
      n * factorial(n - 1)
Scala - Higher-Order Functions

Scala allows the definition of higher-order
functions. These are functions that take other
functions as parameters, or whose result is a
function. For example in the following code,
apply() function takes another function f and a
value v and applies function f to v:
Scala - Higher-Order Functions


object Test {
    def main(args: Array[String]) {


      println( apply( layout, 10) )
}
    def apply(f: Int => String, v: Int) = f(v)


    def layout[A](x: A) = "[" + x.toString() + "]"


}
Scala - Anonymous Functions

Scala provides a relatively lightweight syntax for
defining anonymous functions. Anonymous
functions in source code are called function
literals and at run time, function literals are
instantiated into objects called function values.


Scala supports first-class functions, which means
you can express functions in function literal
syntax, i.e., (x: Int) => x + 1, and that functions
Scala - Anonymous
Functions
var inc = (x:Int) => x+1


Variable inc is now a function that can be used the
usual way:
var x = inc(7)-1
It is also possible to define functions with multiple
parameters as follows:
var mul = (x: Int, y: Int) => x*y
Variable mul is now a function that can be used the
Scala - Currying Functions
Currying transforms a function that takes multiple
parameters into a chain of functions, each taking
a single parameter. Curried functions are defined
with multiple parameter lists, as follows:


def strcat(s1: String)(s2: String) = s1 + s2


Alternatively, you can also use the following
syntax to define a curried function:
Scala - Currying Functions


object Test {
    def main(args: Array[String]) {
        val str1:String = "Hello, "
        val str2:String = "Scala!"
        println( "str1 + str2 = " + strcat(str1)(str2) )
    }
def strcat(s1: String)(s2: String) = {
        s1 + s2
    }
}
Scala - Closures
A closure is a function whose return value depends on
the value of one or more variables declared outside
this function. Consider the following piece of code with
anonymous function:
val multiplier = (i:Int) => i * 10
Here 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 * factor
There are two free variables in multiplier: i and factor.
One of them, i, is a formal parameter to the function.
Scala - Closures


object Test {
    def main(args: Array[String]) {
        println( "muliplier(1) value = " + multiplier(1) )
        println( "muliplier(2) value = " + multiplier(2) )
    }
    var factor = 3
    val multiplier = (i:Int) => i * factor
}
Above function references factor and reads its current value each time. If a
function has no external references, then it is trivially closed over itself. No
external context is required.
PROBLEM
class 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 of
scala> tc.test, scala> tc.test and scala> tc.test
Thank you

More Related Content

What's hot

Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheoryKnoldus Inc.
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesTomer Gabel
 
Procedure Typing for Scala
Procedure Typing for ScalaProcedure Typing for Scala
Procedure Typing for Scalaakuklev
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldBTI360
 
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...Sanjeev_Knoldus
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako, Vasil Remeniuk
 

What's hot (17)

Scala Intro
Scala IntroScala Intro
Scala Intro
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheory
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
Introducing scala
Introducing scalaIntroducing scala
Introducing scala
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Procedure Typing for Scala
Procedure Typing for ScalaProcedure Typing for Scala
Procedure Typing for Scala
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
Scala test
Scala testScala test
Scala test
 
Scala
ScalaScala
Scala
 
Google06
Google06Google06
Google06
 
1.2 scala basics
1.2 scala basics1.2 scala basics
1.2 scala basics
 
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
Scala traits training by Sanjeev Kumar @Kick Start Scala traits & Play, organ...
 
Metaprogramming in Scala 2.10, Eugene Burmako,
Metaprogramming  in Scala 2.10, Eugene Burmako, Metaprogramming  in Scala 2.10, Eugene Burmako,
Metaprogramming in Scala 2.10, Eugene Burmako,
 
Scala 2013 review
Scala 2013 reviewScala 2013 review
Scala 2013 review
 

Similar to Functional Objects & Function and Closures

Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and ClosuresSandip Kumar
 
Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and ClosuresSandip Kumar
 
Functions & closures
Functions & closuresFunctions & closures
Functions & closuresKnoldus Inc.
 
Functions & Closures in Scala
Functions & Closures in ScalaFunctions & Closures in Scala
Functions & Closures in ScalaKnoldus Inc.
 
ScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxjkapardhi
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scalaehsoon
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalUrs Peter
 
The Ring programming language version 1.6 book - Part 33 of 189
The Ring programming language version 1.6 book - Part 33 of 189The Ring programming language version 1.6 book - Part 33 of 189
The Ring programming language version 1.6 book - Part 33 of 189Mahmoud Samir Fayed
 
Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010JUG Lausanne
 
Programming in Scala - Lecture Three
Programming in Scala - Lecture ThreeProgramming in Scala - Lecture Three
Programming in Scala - Lecture ThreeAngelo Corsaro
 

Similar to Functional Objects & Function and Closures (20)

Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and Closures
 
Scala oo (1)
Scala oo (1)Scala oo (1)
Scala oo (1)
 
Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and Closures
 
Scala tutorial
Scala tutorialScala tutorial
Scala tutorial
 
Scala tutorial
Scala tutorialScala tutorial
Scala tutorial
 
Functions & Closures in Scala
Functions & Closures in ScalaFunctions & Closures in Scala
Functions & Closures in Scala
 
Functions & closures
Functions & closuresFunctions & closures
Functions & closures
 
Functions & Closures in Scala
Functions & Closures in ScalaFunctions & Closures in Scala
Functions & Closures in Scala
 
ScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptxScalaLanguage_ch_4_5.pptx
ScalaLanguage_ch_4_5.pptx
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
 
Functional object
Functional objectFunctional object
Functional object
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_final
 
MA3696 Lecture 9
MA3696 Lecture 9MA3696 Lecture 9
MA3696 Lecture 9
 
The Ring programming language version 1.6 book - Part 33 of 189
The Ring programming language version 1.6 book - Part 33 of 189The Ring programming language version 1.6 book - Part 33 of 189
The Ring programming language version 1.6 book - Part 33 of 189
 
Scala basic
Scala basicScala basic
Scala basic
 
Lab Manual-OOP.pdf
Lab Manual-OOP.pdfLab Manual-OOP.pdf
Lab Manual-OOP.pdf
 
Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010
 
Of Lambdas and LINQ
Of Lambdas and LINQOf Lambdas and LINQ
Of Lambdas and LINQ
 
Programming in Scala - Lecture Three
Programming in Scala - Lecture ThreeProgramming in Scala - Lecture Three
Programming in Scala - Lecture Three
 
Scala in a nutshell by venkat
Scala in a nutshell by venkatScala in a nutshell by venkat
Scala in a nutshell by venkat
 

Recently uploaded

UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXTarek Kalaji
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 

Recently uploaded (20)

UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
VoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBXVoIP Service and Marketing using Odoo and Asterisk PBX
VoIP Service and Marketing using Odoo and Asterisk PBX
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 

Functional Objects & Function and Closures

  • 1. Functional Objects & Function and Closures < Sandip Kumar > sandip@knoldus.com
  • 2. Programming with Functional Objects in Scala Scala is the perfect mixture of Object Oriented (OO) and Functional Programming (FP). You get the flexibility of FP along with the familiarity of OO; along with the awesome power of the Actor model.
  • 3. What is the Functional Object 1- A function in Scala is a complete object. There are a series of traits in Scala to represent functions with various numbers of arguments: Function0, Function1, Function2, etc 2- As an instance of a class that implements one of these traits, a function object has methods 3-One of these methods is the apply method, which contains the code that implements the body of the function. 4-Scala has special "apply" syntax: if you write a symbol name followed by an argument list in parentheses (or just a pair of parentheses for an empty argument list), Scala converts that into a call to the apply method for the named object.
  • 4. What is the Functional Object 5-When we create a variable whose value is a function object and we then reference that variable followed by parentheses, that gets converted into a call to the apply method of the function object. 6-When we treat a method as a function, such as by assigning it to a variable, Scala actually creates a function object whose apply method calls the original method, and that is the object that gets assigned to the variable. 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 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.
  • 6. Scala is a functional language, in the sense that every function is a Value. If functions are values, and values are objects, it follows that functions themselves are objects. The function type S => T is equivalent to scala.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, the anonymous 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 body return [expr] }
  • 8. Function Implementation A function which does not return anything can return Unit which is equivalent to void in Java and indicates that function does not return anything. The functions which do not return anything in Scala, they are called procedures. Following is the syntax object Hello{ def printMe( ) : Unit = {
  • 9. Calling Functions: Scala provides a number of syntactic variations for invoking methods. Following is the standard way to call a method: functionName( list of parameters ) If 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
  • 10. Fun With Scala Functions scala> def method1() = { println("method1") } method1: ()Unit scala> def method2(str: String) = { println("method2: " + str) } method2: (String)Unit scala> def method3(str: String): Int = {
  • 11. Fun With Scala Functions scala> method1 method1 scala> method2("abc") method2: abc scala> method3("abcdefg")
  • 12. Fun With Scala Functions * When we type “def method1() = {…}” we actually declared an instance of a special class. I’ll declare method1 again, but with the underlying object exposed: scala> val method1 = new Function0[Unit] { | def apply: Unit = { println("method1") } |} method1: java.lang.Object with () => Unit = <function> scala> method1 res1: java.lang.Object with () => Unit = <function> scala> method1.apply method1 scala> method1() method1
  • 13. #We instantiate an instance of trait Function0[Unit] and implement its one abstract method, called apply, and assign it to a val named method1. Now you can see method1 is actually just a plain old Scala object. When we type in “method1″ and hit enter, the interpreter just tells us the resulting value of the statement which is an Object with trait Function0. Hmm, that didn’t work. Next we try calling the apply method on the object. #But it’s just a regular call to a member method. But when we type “method1()” then Scala knows that we want to use this object as a function, and that we’re not refering to the object itself. When you declare a function using “def” Scala assumes
  • 14. That Function0[Unit], by the way, defines a function that takes 0 parameters and returns Unit (which is to say nothing as in Java void (not to be confused with Nothing)). If 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 the function parameter types, and the last of which defines the return type.
  • 15. scala> def method2 = { println("method2") } method2: Unit scala> val m2: () => Unit = method2 <console>:5: error: type mismatch; found : Unit required: () => Unit val m2: () => Unit = method2 ^ scala> def method2() = { println("method2") } method2: ()Unit
  • 16. # First we just define a function called method2. Nothing fancy. Then we try to assign it to a val of type () => Unit. It fails. See the error message? Found : Unit. It parses it all wrong. Scala thinks we’re trying to call method2 and assign the result to m2. How can we set things straight? Well, one way is to slightly change the way we define method2. The only difference in the first and second definition is the addition of an empty parameter list, that empty pair parentheses. # For some reason, when we define the method in this apparently equivalent fashion, Scala rightly interprets our intentions and allows us to assign to m2. There is another way, though. In the third definition of method2, we’ve again removed the parentheses. But this time we assign it successfully to val m2 by following method2 with an underscore. The underscore just causes Scala to treat method2 as a Function0 object, rather than attempting to invoke it.
  • 17. Fun With Scala Functions 1-We instantiate an instance of trait Function0[Unit] and implement its one abstract method, called apply, and assign it to a val named method1. 2-Now you can see method1 is actually just a plain old Scala object. When we type in “method1″ and hit enter, the interpreter just tells us the resulting value of the statement which is an Object with trait Function0. Hmm, that didn’t work.
  • 18. Fun With Scala Functions If 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 the function parameter types, and the last of which defines the return type.
  • 19. trait Function3[-T1, -T2, -T3, +R] extends AnyRef { ... def apply( v1 :T1, v2 :T2, v3 :T3 ) : R ... }
  • 20. Fun With Scala Functions scala> def method2 = { println("method2") } method2: Unit scala> val m2: () => Unit = method2 <console>:5: error: type mismatch; found : Unit required: () => Unit val m2: () => Unit = method2 ^ * we just define a function called method2.
  • 21. Fun With Scala Functions 1-The only difference in the first and second definition is the addition of an empty parameter list, that empty pair parentheses. For some reason, when we define the method in this apparently equivalent fashion, Scala rightly interprets our intentions and allows us to assign to m2. 2- In the third definition of method2, we’ve again removed the parentheses. But this time we assign it successfully to val m2 by following method2 with an underscore. The underscore just causes Scala to treat method2 as a
  • 22. Scala - Functions Call-by-Name A call-by-name mechanism passes a code block to the callee and each time the callee accesses the parameter, the code block is executed and the value is calculated.
  • 23. Functions Call-by-Name object Test { def main(args: Array[String]) { delayed(time()); } def time() = {
  • 24. Scala - Function with Variable Arguments Scala allows you to indicate that the last parameter to a function may be repeated. This allows clients to pass variable length argument lists to the function. Following is a simple example to show the concept.
  • 25. Function with Variable Arguments object Test { def main(args: Array[String]) { printStrings("Hello", "Scala", "Python"); } def printStrings( args:String* ) = { var i : Int = 0; for( arg <- args ){ println("Arg value[" + i + "] = " + arg ); i = i + 1; }
  • 26. Scala - Default Parameter Values for a Function Scala lets you specify default values for function parameters. The argument for such a parameter can optionally be omitted from a function call, in which case the corresponding argument will be filled in with the default. Following is an example of specifiying default parameters:
  • 27. Default Parameter Values for a Function object Test { def main(args: Array[String]) { println( "Returned Value : " + addInt() ); } def addInt( a:Int=5, b:Int=7 ) : Int = { var sum:Int = 0 sum = a + b return sum } }
  • 28. Scala - Nested Functions Scala allows you to define functions inside a function and functions defined inside other functions are called local functions. Here is an implementation of a factorial calculator, where we use a conventional technique of calling a second, nested method to do the work
  • 29. Scala - Nested Functions object Test { def main(args: Array[String]) { println( factorial(0) println( factorial(1) ) println( factorial(2) ) println( factorial(3) ) } def factorial(i: Int): Int = { def fact(i: Int, accumulator: Int): Int = { if (i <= 1) accumulator else fact(i - 1, i * accumulator) } fact(i, 1)}}
  • 30. Scala - Partially Applied Functions When you invoke a function, you're said to be applying the function to the arguments. If you pass all the expected arguments, you have fully applied it. If you send only a few arguments, then you get back a partially applied function. This gives you the convenience of binding some arguments and leaving the rest to be filled in later. Following is a simple example to show the concept:
  • 31. Scala - Partially Applied Functions import java.util.Date object Test { def main(args: Array[String]) { val date = new Date log(date, "message1" ) log(date, "message2" ) log(date, "message3" ) }
  • 32. Scala - Partially Applied Functions *Here the log( ) method takes two parameters: date and message. We want to invoke the method multiple times, with the same value for date but different values for message. We can eliminate the noise of passing the date to each call by partially applying that argument to the log( ) method. To do so, # we first bind a value to the date parameter and leave the second parameter unbound by putting an underscore at its place. The result is a partially applied function that we've stored in a variable.
  • 33. Scala - Functions with Named Arguments Named arguments allow you to pass arguments to a function in a different order. The syntax is simply that each argument is preceded by a parameter name and an equals sign. Following is a simple example to show the concept:
  • 34. Functions with Named Arguments object Test { def main(args: Array[String]) { printInt(b=5, a=7); } def printInt( a:Int, b:Int ) = { println("Value of a : " + a ); println("Value of b : " + b ); } }
  • 35. Scala - Recursion Functions object Test { def main(args: Array[String]) { for (i <- 1 to 10) println( "Factorial of " + i + ": = " + factorial(i) ) } def factorial(n: BigInt): BigInt = { if (n <= 1) 1 else n * factorial(n - 1)
  • 36. Scala - Higher-Order Functions Scala allows the definition of higher-order functions. These are functions that take other functions as parameters, or whose result is a function. For example in the following code, apply() function takes another function f and a value v and applies function f to v:
  • 37. Scala - Higher-Order Functions object Test { def main(args: Array[String]) { println( apply( layout, 10) ) } def apply(f: Int => String, v: Int) = f(v) def layout[A](x: A) = "[" + x.toString() + "]" }
  • 38. Scala - Anonymous Functions Scala provides a relatively lightweight syntax for defining anonymous functions. Anonymous functions in source code are called function literals and at run time, function literals are instantiated into objects called function values. Scala supports first-class functions, which means you can express functions in function literal syntax, i.e., (x: Int) => x + 1, and that functions
  • 39. Scala - Anonymous Functions var inc = (x:Int) => x+1 Variable inc is now a function that can be used the usual way: var x = inc(7)-1 It is also possible to define functions with multiple parameters as follows: var mul = (x: Int, y: Int) => x*y Variable mul is now a function that can be used the
  • 40. Scala - Currying Functions Currying transforms a function that takes multiple parameters into a chain of functions, each taking a single parameter. Curried functions are defined with multiple parameter lists, as follows: def strcat(s1: String)(s2: String) = s1 + s2 Alternatively, you can also use the following syntax to define a curried function:
  • 41. Scala - Currying Functions object Test { def main(args: Array[String]) { val str1:String = "Hello, " val str2:String = "Scala!" println( "str1 + str2 = " + strcat(str1)(str2) ) } def strcat(s1: String)(s2: String) = { s1 + s2 } }
  • 42. Scala - Closures A closure is a function whose return value depends on the value of one or more variables declared outside this function. Consider the following piece of code with anonymous function: val multiplier = (i:Int) => i * 10 Here 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 * factor There are two free variables in multiplier: i and factor. One of them, i, is a formal parameter to the function.
  • 43. Scala - Closures object Test { def main(args: Array[String]) { println( "muliplier(1) value = " + multiplier(1) ) println( "muliplier(2) value = " + multiplier(2) ) } var factor = 3 val multiplier = (i:Int) => i * factor } Above function references factor and reads its current value each time. If a function has no external references, then it is trivially closed over itself. No external context is required.
  • 44. PROBLEM class 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 of scala> tc.test, scala> tc.test and scala> tc.test