Search code examples
scalafunctional-programminghigher-order-functions

Can someone help me understand this snippet of code?


Fundamentally, I know what this code does, but I'm trying to fully understand the logic in withTempDir.

private def withTempDir(input: File => Unit): Unit = {
  val tempFolder = Files.createTempDirectory("temporalOutput")
  tempFolder.toFile.deleteOnExit()
  input(tempFolder.resolve("output").toFile)
}

withTempDir {
  x => 
    println(x.getAbsoluteFile.toString)
}

Is the input(tempFolder.resolve("output").toFile) actually needed there? What's its purpose? Could it be just tempFolder.resolve("output").toFile?


Solution

  • With input in the last line of

    private def withTempDir(input: File => Unit): Unit = {
      val tempFolder = Files.createTempDirectory("temporalOutput")
      tempFolder.toFile.deleteOnExit()
      input(tempFolder.resolve("output").toFile)
    }
    

    the code

    withTempDir {
      x => 
        println(x.getAbsoluteFile.toString)
    }
    

    is the same as

    val tempFolder = Files.createTempDirectory("temporalOutput")
    tempFolder.toFile.deleteOnExit()
    println(tempFolder.resolve("output").toFile.getAbsoluteFile.toString)
    

    Here in the last line the function input i.e. currently x => println(x.getAbsoluteFile.toString) was applied to x being tempFolder.resolve("output").toFile.

    If you remove input in the last line of withTempDir i.e. you have just

    private def withTempDir(input: File => Unit): Unit = {
      val tempFolder = Files.createTempDirectory("temporalOutput")
      tempFolder.toFile.deleteOnExit()
      tempFolder.resolve("output").toFile
    }
    

    then withTempDir will not depend on input at all, so it will be like

    private def withTempDir/*(input: File => Unit)*/: Unit = {
      val tempFolder = Files.createTempDirectory("temporalOutput")
      tempFolder.toFile.deleteOnExit()
      tempFolder.resolve("output").toFile
    }
    

    and then in

    withTempDir {
      x => 
        println(x.getAbsoluteFile.toString)
    }
    

    application of withTempDir to x => println(x.getAbsoluteFile.toString) will not make much sense, it will be the same withTempDir i.e.

    val tempFolder = Files.createTempDirectory("temporalOutput")
    tempFolder.toFile.deleteOnExit()
    tempFolder.resolve("output").toFile
    

    When you define private def withTempDir(input: File => Unit): Unit this means you can apply withTempDir to different functions input: File => Unit.

    withTempDir is a so called higher-order function since it accepts another function.

    https://docs.scala-lang.org/tour/higher-order-functions.html