error: ':' expected but identifier found

Paul Draper picture Paul Draper · Apr 17, 2014 · Viewed 9k times · Source

Since type is a reserved word, I append an underscore when using it as an identifier. (I can find no style recommendation about this.)

val type_ = "abc"

But then I used it as an argument identifier.

def f(id: String, type_: String, typeName: String) = Map(
    "id" -> id,
    "type" -> type_,
    "typeName" -> typeName
)

println(f("a", "simple", "test"))

But I get an error

error: identifier expected but 'type' found.
def f(type: String) = 1

Putting a space between type_ and : fixes it

def f(id: String, type_ : String, typeName: String)

though this goes against the recommended Scala style.

Is this a bug in the Scala compiler? I haven't been able to find any sort of grammar for Scala syntax, so I can't be sure.

Answer

Noah picture Noah · Apr 17, 2014

In scala the _ in variable names is specifically used to denote that all of the following characters are part of the variable name up until a white space. So in your case type_ is a fine variable name, but when you put it in a method signature type_: it infers the colon as part of the variable name since there's no white space between the colon and underscore. For more detail you can see page 54 of Programming Scala.

Paraphrased from the book, the reason they did this is so you can do things like xyz_++= as a variable or method name since xyz++= would be interperepted as the operator xyz ++=.