Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deprecation warning when compiling: eta expansion of zero argument method

Tags:

scala

When compiling this snippet, the scala compiler issues the following warning:

Eta-expansion of zero-argument method values is deprecated. Did you intend to write Main.this.porFiles5()? [warn] timerFunc(porFiles5)

It occurs when I pass a function to another one for a simple timing. The timer function takes a parameterless function returning unit, at this line: timerFunc(porFiles5). Is this warning necessary? What would be the idiomatic way to avoid it?

package example
import java.nio.file._
import scala.collection.JavaConverters._
import java.time._
import scala.collection.immutable._

object Main extends App {

  val dir = FileSystems.getDefault.getPath("C:\\tmp\\testExtract")

  def timerFunc (func:()=>Unit ) = {
    val start = System.currentTimeMillis()
    timeNow()
    func()
    val finish = System.currentTimeMillis()
    timeNow()
    println((finish - start) / 1000.0 + " secs.")
    println("==================")
  }

  def porFiles5(): Unit = {
    val porFiles5 = Files.walk(dir).count()
    println(s"You have $porFiles5 por5 files.")
  }

  def timeNow(): Unit = {
    println(LocalTime.now)
  }

  timeNow()
  timerFunc(porFiles5)
  timeNow()

}
like image 368
s952163 Avatar asked Aug 13 '17 06:08

s952163


1 Answers

porFiles5 is not a function. It is a method, which is something completely different in Scala.

If you have a method, but you need a function, you can use η-expansion to lift the method into a function, like this:

someList.foreach(println _)

Scala will, in some cases, also perform η-expansion automatically, if it is absolutely clear from context what you mean, e.g.:

someList.foreach(println)

However, there is an ambiguity for parameterless methods, because Scala allows you to call parameterless methods without an argument list, i.e. a method defined with an empty parameter list can be called without any argument list at all:

def foo() = ???
foo // normally, you would have to say foo()

Now, in your case, there is an ambiguity: do you mean to call porFiles5 or do you mean to η-expand it? At the moment, Scala arbitrarily disambiguates this situation and performs η-expansion, but in future versions, this will be an error, and you will have to explicitly perform η-expansion.

So, to get rid of the warning, simply use explicit η-expansion instead of implicit η-expansion:

timerFunc(porFiles5 _)
like image 76
Jörg W Mittag Avatar answered Oct 21 '22 17:10

Jörg W Mittag