views:

131

answers:

2

How to pass by-name repeated parameters in Scala?

The following code fails to work:

scala> def foo(s: (=> String)*) = {
<console>:1: error: no by-name parameter type allowed here
       def foo(s: (=> String)*) = {
                   ^

Is there any other way I could pass a variable number of by name parameters to the method?

+4  A: 

Repeated by-name parameters are not currently supported.

Randall Schulz
+1  A: 

This isn't very pretty but it allows you to pass byname parameters varargs style

def printAndReturn(s: String) = {
  println(s)
  s
}

def foo(s: (Unit => String)*) {
  println("\nIn foo")
  s foreach {_()}  // Or whatever you want ...
}

foo()

foo((Unit) => printAndReturn("f1"),
    (Unit) => printAndReturn("f2"))

This produces

In foo

In foo f1 f2

Don Mackenzie
It's certainly not pleasant to look at nor to write. And I continue to encourage people to distinguish by-name parameters (that are *implemented* using a thunk but are otherwise logically distinct) and function values used as arguments. Likewise for methods and functions.
Randall Schulz
will do. Thanks.
Green Hyena
I think Randall's comments are fair, the above could be perhaps improved with a helper function to wrap / pre-process the arguments, for example: def deferred(block: => String) = () => blockwith foo altered to: def foo(s: (() => String)*)giving, for example:foo(deferred {val a = "apples"; "Green "+apples}, deferred {"Pears"})
Don Mackenzie