BAR
BAR

Reputation: 17111

Scala Passing Function with Argument

The Scala example for passing a function to another function lacks the case where the passed function (timeFlies) takes an argument (x).

object Timer {
  def oncePerSecond(callback: (Int) => Unit) {
    while (true) { callback(x); Thread sleep 1000 }
  }
  def timeFlies(x: int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies(5))
  }
}

How can I make the above code work?

Edit: I added an x in the oncepersecond to clarify the goal is to pass the integer.

Upvotes: 17

Views: 18873

Answers (5)

Chanpreet Chhabra
Chanpreet Chhabra

Reputation: 384

Passing the function as an argument

def function1(callback: Int => Unit): Unit = {
  // do something
}

def callback_function(x: Int): Unit = {
   // do something
}

function1(callback_function)

If you want to pass reference of the function to a variable you can do the following...

let say we have function..

def handleLogic(x: Int): Unit => {
   // do something
}

val method = handleLogic _

or

val method = handleLogic(_)

Upvotes: 0

Karl Bielefeldt
Karl Bielefeldt

Reputation: 49028

There are at least two ways you can do it, depending on where exactly you want to pass the argument in. The first way is where you keep main like you had it.

object Timer {
  def oncePerSecond(callback: => Unit) {
    while (true) { callback; Thread sleep 1000 }
  }
  def timeFlies(x: Int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies(5))
  }
}

The other method is to pass the parameter in at the point of the callback, like this:

object Timer {
  def oncePerSecond(callback: (Int) => Unit) {
    val x = 5
    while (true) { callback(x); Thread sleep 1000 }
  }
  def timeFlies(x: Int) {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]) {
    oncePerSecond(timeFlies)
  }
}

Note that timeFlies has the signature (Int) => Unit, but timeFlies(5) has the signature => Unit, because of partial application. This basically means you can apply the parameter to automatically create a function that takes fewer parameters. oncePerSecond needs to know in its signature if you've already applied the Int parameter to the callback or not.

Both methods are useful for different use cases. The first way lets oncePerSecond not have to know about the callback's parameters. The second way lets you change the value of x every time through the loop if you want.

Upvotes: 24

Michael Zajac
Michael Zajac

Reputation: 55569

The parameter callback: () => Unit is a zero-parameter function that returns Unit. You should make it call-by-name parameter (something that evaluates to Unit):

def oncePerSecond(callback: => Unit) = ...

Upvotes: 0

John
John

Reputation: 31

The return type of timeFlies will be Unit, not Function. Perhaps you meant:

oncePerSecond(() => timeFlies(5))

Upvotes: 3

Ryoichiro Oka
Ryoichiro Oka

Reputation: 1997

oncePerSecond(() => timeFlies(5))

or

def oncePerSecond(callback: => Unit) {...

Upvotes: 2

Related Questions