Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Omitting dots when chaining calls

Tags:

syntax

scala

I don't understand why the following code doesn't compile:

class Abc 
{
    def b (x : String) = x + "abc"

    def a (y : String) =
    {
        val ls : List[String] = y.lines toList
        b (ls.head)
    }
}

Main.scala:8: error: type mismatch; found : java.lang.String required: Int b (ls.head)

When I change "y.lines toList" to

y.lines.toList

or even to

y.lines toList;

it does compile.

Perhaps the compiler understands it like

(y.lines).toList(b (ls.head))

or something like that, but I still don't understand the rules.

like image 400
Ady Gil Avatar asked Jan 28 '11 02:01

Ady Gil


2 Answers

It's not obvious, and it's a combination of Scala's shortcut syntax and list indexing. If you want a hint, try redefining b to:

def b(x : String) = 0

You'll get some other compiler garbage back, but the error will change. In short, the Scala compiler will let you omit parens and dots for zero- or one-parameter methods, and we know b looks like it's somehow getting chained.. The rub is that Scala also uses parens for list indexing, so toList, which returns an iterator, may take one parameter as the list index. I'm not sure of this part exactly, but it looks like once you start omitting dots, the lexer will become greedy, and when it comes across a method that may take one parameter, will attempt to pass the next statement to it. In this case, that's a string, so it throws a syntax error.

like image 98
Marc Bollinger Avatar answered Oct 10 '22 10:10

Marc Bollinger


You got it spot on with this:

(y.lines).toList(b (ls.head))

With the only possible correction being:

(y.lines).toList(b).apply(ls.head)

I'm not sure that Scala would decide in this particular case.

The rule, roughly speaking, is object (method parameters)* [method]. The compiler will continue as long as it finds tokens for a valid expression. A ; finishes the expression, and so would a ) or }. If the next line is blank, the expression also ends. If the next line begins with a reserved keyword (val, def, if, etc), the expression would end too.

like image 20
Daniel C. Sobral Avatar answered Oct 10 '22 09:10

Daniel C. Sobral