scalacode
scalacode

Reputation: 1106

Call by name parameters in scala functions

I have a question concerning the difference between these two functions:

def getFunction(checkpointPath: String,
                  sparkConf: SparkConf,
                  creatingFunc: () => StreamingContext): StreamingContext = {
    function body
  }


def getFunction(checkpointPath: String,
                  sparkConf: SparkConf,
                  creatingFunc:  => StreamingContext): StreamingContext = {
    function body
  }

so the called by name param is the same:

creatingFunc:  => StreamingContext 

and

creatingFunc: () => StreamingContext

or no ?

Upvotes: 2

Views: 90

Answers (2)

francoisr
francoisr

Reputation: 4585

The answer from Mario is right: they are not the same. However, they are often used for the exact same purposes, and the choice between the two often relates to syntax rather than semantics.

For example, you could want to write a repeat method that repeats a given block of code in two ways:

def repeat1(n: Int)(block: () => Unit): Unit = ???
def repeat2(n: Int)(block: => Unit): Unit = ???

The definitions are almost the same, but their usage at call-site are not:

repeat1(10) { () => 
    // my awesome code goes here
}

repeat2(10) { 
    // my awesome code goes here
}

The second choice feels much more natural in this case: it looks almost like repeat is part of the language just like while now!

This nice syntax is widely used when creating Domain-Specific Languages within Scala (DSLs). For everything else, I prefer to be explicit and use the Function0 definition, because it's easier to keep track of exactly when the value gets computed.

Upvotes: 3

Mario Galic
Mario Galic

Reputation: 48400

The two are not the same. The first case specifies method parameter that is call-by-name

creatingFunc:  => StreamingContext 

whilst the second case specifies pass-by-value method parameter where the parameter happens to be a function of type () => StreamingContex

creatingFunc: () => StreamingContext

For example, consider the following two methods

def foo(arg: () => String) = ""
def foo(arg: => String) = ""

then

foo(() => "") // resolves to call first foo
foo("")       // resolves to call second foo

Upvotes: 5

Related Questions