How to pass a function as argument to a scala function

Scala is a functional programming language and passing functions as args is one of most or the most widely used syntax in scala and similar functional programming languages. For instance, to the map function , typically we pass our lambda expression as an argument and this is the case with most of the functions available in scala. Let us understand this with an example

package com.stackrules.examples

/**
  * Example showcasing how a function can be passed to another function
  */
object FunctionExample extends App{


  /**
    * Marks the word boundary using the | separator
    * Accepts two arguments, the input string and any function that returns a string
    * @param input
    * @param fn
    * @return
    */
  def markWords(input:String, fn:String=>String) = {
     fn(input.split(" ").mkString("|"))
  }

  /**
    * Simple function that turns a given string to upper case
    * @param input
    * @return
    */
  def makeUpper(input:String):String = {
    input.toUpperCase
  }

  val response = markWords("Hello World Program",makeUpper)
  println(response)

}

1. The markWords function accepts two arguments, the input and any function that accepts a string as argument and returns another string

2. markWords is a very simple function that breaks the given string to words and outputs a string with | marking word boundary.

3. This output can be further transformed using any function. In the example above, we used makeUpper function to convert the output to upper case

4. The String class itself contains toUpperCase method, but we just used our own function to illustrate how to pass another function as argument.

Let us also look at anonymous functions with more than one argument. For instance, how we can use an anonymous function with two arguments. This is also can be easily understood using an example. See below.

package com.stackrules.examples

/**
  * Demonstrates the usage of a function accepting another function with two arguments
  */
object FunctionExampleTwo  extends App{

  /**
    * Calculate the Square of a number
    * @param input
    * @param fn
    * @return
    */
  def square(input:Int, fn:(Int,Int)=>Int) = {
    val square = input*input
    fn(square,square)
  }
  /**
    * Adds two numbers
    * @param num1
    * @param num2
    * @return
    */
  def add(num1:Int,num2:Int):Int = {
    num1+num2
  }

  //Simple addition of squares
  val response = square(10,add)
  println(response)

  // Passing an empty function that returns the input as is, such that we get only the square
  // A better mechanism is to make the function optional using Option. The intention here is just to

  // show how we can pass an empty function
  println(square(10,(x:Int,y:Int)=>x))

}

The square function takes a number and another function with two arguments. It calculates the square and the result is passed to the supplied function

In the above code refer the line below with comment //Simple addition of squares , in this we pass another function (add) to the square function resulting in the addition of the squared value with itself.

What if we don’t want any other transformation and just the square. In that case we can pass an empty function to the square function. This is illustrated in the last line

There are better ways of doing that by declaring the function argument as optional. But this tutorials aim is to show case how to pass function as arguments hence we don’t need to bother about that for now.

If the passed function needs multiple arguments, make sure the arguments are declared in the parent function. For instance

package com.stackrules.examples

/**
  * Example showing how to pass multiple arguments 
  */

object FunctionExampleThree extends App{

  /**
    * Calculate the Square of a number
    * @param constant
    * @param fn
    * @return
    */
  def square(x:Int, constant:Int,fn:(Int,Int)=>Int) = {
    val square = x*x
    fn(square,constant)
  }
  /**
    * Adds two numbers
    * @param num1
    * @param num2
    * @return
    */
  def add(num1:Int,num2:Int):Int = {
    num1+num2
  }

  val response = square(10,1000,add)
  println(response)

}

In example above, a constant that gets added to the squared value. Observe that the square function now declares three arguments

1. x – the number to square

2. constant – the constant that needs to be added to the squared value

3. The function that needs to be invoked after the square operation.

Note: the second argument to the square function is solely for passing to the supplied add function.

Leave a Comment