object Parens {
  def parameterless: String = "foo"
  def emptyParens(): String = "bar"

  def fireNukes(): String = "nukes fired"

  def log(f: () => String): Unit = { println("fn: " + f) }
  def log(msg: String): Unit = { println("string: " + msg) }

  def main(args: Array[String]) {
    // all of the xi's have type String, which may be surprising (you might
    // thing some should be `() => String`.
    val x1 = parameterless
    // val x2 = parameterless() // fails, tries to call .apply() on return value
    // of `paremeterless` (i.e. String#apply())

    val x3 = emptyParens
    val x4 = emptyParens()

    val f1: () => String = emptyParens

    // so a bare `emptyParens` can have its type inferred quite differently
    // depending on context.

    // val f2: () => String = parameterless // fails, need trailing ` _` to get
    // scalac to treat parameterless as a Function0
    val f2: () => String = parameterless _

    println(x1, x3, x4, f1, f2)

    log(fireNukes) // what happens here? fireNukes is executed, though it's not clear which log() override will get called
  }
}