Themerius
Themerius

Reputation: 1911

Scala variable argument list with call-by-name possible?

I've got some code like this:

def foo (s: => Any) = println(s)

But when I want to transform this to an argument list with variable length, it won't compile anymore (tested on Scala 2.10.0-RC2):

def foo (s: => Any*) = println(s)

What must I write, that it works like this?

Upvotes: 9

Views: 1492

Answers (2)

som-snytt
som-snytt

Reputation: 39577

There is an issue: https://issues.scala-lang.org/browse/SI-5787

For the accepted answer, to recover the desired behavior:

object Test {
  import scala.language.implicitConversions
  implicit def byname_to_noarg[A](a: => A) = () => a
  implicit class CBN[A](block: => A) {
    def cbn: A = block
  }
  //def foo(s: (() => Any)*) = s.foreach(a => println(a()))
  def foo(s: (() => Any)*) = println(s(1)())
  def goo(a: =>Any, b: =>Any, c: =>Any) = println(b)

  def main(args: Array[String]) {
    foo("fish", Some(7), {println("This still happens first"); true })
    goo("fish", Some(7), {println("This used to happens first"); true })
    foo("fish", Some(7), {println("This used to happens first"); true }.cbn)
  }
}

Excuse the lolcats grammar.

Upvotes: 6

Rex Kerr
Rex Kerr

Reputation: 167871

You have to use zero-argument functions instead. If you want, you can

implicit def byname_to_noarg[A](a: => A) = () => a

and then

def foo(s: (() => Any)*) = s.foreach(a => println(a()))

scala> foo("fish", Some(7), {println("This still happens first"); true })
This still happens first
fish
Some(7)
true

Upvotes: 11

Related Questions