Sunday, September 29, 2013

Higher Order functions in Scala

The other day I was experimenting with functional programming in scala and  the concept of first class functions.

A programming language is said to support first class functions if

  1. Functions can be passed as parameters to another function.
  2. Functions can be returned from another function.
  3. Functions can be assigned to a variable in the same ways as any other first class object or primitive data types can be assigned to a variable.
  4. Functions can be defined within another function.
A corollary to this is that first class functions in a programming language lead to the language supporting closures since it has to clearly define what variables and values are being referred to by inner functions.

Exploring all these things in Scala made me write some sample code to demonstrate these concepts.
Below is a scala function which demonstrates all these concepts.

// 1.Takes a function as input, 
// 2.creates a nested function and assigns it to a variable,
//  3. applies the input function to input variables
 // 4. returns a function
  def firstclassfunc(inputfunc:(Int)=> Int, inputparam:Int): (Int,Int) => Int = {
    //val innerfunc = (x:Int, y:Int) => inputfunc(inputparam+x+y)
    val innerfunctionliteral =  (x:Int, y:Int)=> { inputfunc(inputparam+x+y) } 
    def anotherinnerfunc(x:Int, y:Int):Int = {inputfunc(inputparam+x+y)}
    val innerfunctionvalclassrepresentation = new Function2[Int, Int, Int] {
    def apply(x: Int, y:Int): Int = inputfunc(inputparam+x+y)
    val innerfuncdefvalpartiallyapplied =  anotherinnerfunc _
    val innerfuncdefvalinstantiated = anotherinnerfunc(1,2);
    // All of the below scala mechanisms work. As long as we can return a function that can still has accept //two  free variables, it seems we conform to the parent functions' return type definition of (Int,Int) => Int
      return innerfunctionliteral
    // return anotherinnerfunc _
   //  return innerfunctionvalclassrepresentation
   //   return innerfuncdefvalpartiallyapplied
   //  return anotherinnerfunc(_,_)
   // return innerfunctionval