Error with varargs for function-objects in Scala?

Why does this not work?

val f = (args: Int*) => args.sum

error: ')' expected but identifier found.
val f = (args: Int*) => args.sum
                  ^

This however works perfectly fine

def sum(args: Int*) = args.sum
val f = sum _

so does this

val f: (Int*) => Int = args => args.sum

btw. I'm using scala 2.9.1


Solution 1:

I'm not an expert in specification reading, but it looks like the varargs Syntax is not supported for anonymous function.

Compare the syntax for Function Declaration vs Anonymous Functions in the Language Spec

From 4.6 Function Declarations and Definitions

ParamType ::= Type
              | ‘=>’ Type
              | Type ‘*’

6.23 Anonymous Functions

Binding ::= (id | ‘_’) [‘:’ Type]

I have no idea what the reasons for that though. There seem to be reasons but none that can easily be explained. Martin Odersky commented on a request to add varargs for anonymous functions: "This looks tempting at first, but it would drag in a lot of complexity (you just need to believe me on that one)."

Solution 2:

There's also a good explanation on this given by Lex Spoon here here

The syntax is a little misleading here; perhaps it is being too cute. The Any* syntax for varargs makes it look like Any* is itself a type. Really, the * is an annotation on the method parameter, not on the type.

When you write down a function type using the T1=>T2 syntax, both T1 and T2 need to be plain old bona fide types. Scala provides oodles of kinds of types, but vararg types are not one of them.

In practical code, the way out is to explicitly use a sequence type. In fact, if you look at the inferred type for good2, you will see it involves Seq[Any] rather than Any*.