What are the precise rules for when you can omit parenthesis, dots, braces, = (functions), etc.?

You seem to have stumbled upon the answer. Anyway, I’ll try to make it clear.

You can omit dot when using the prefix, infix and postfix notations — the so called operator notation. While using the operator notation, and only then, you can omit the parenthesis if there is less than two parameters passed to the method.

Now, the operator notation is a notation for method-call, which means it can’t be used in the absence of the object which is being called.

I’ll briefly detail the notations.

Prefix:

Only ~, !, + and - can be used in prefix notation. This is the notation you are using when you write !flag or val liability = -debt.

Infix:

That’s the notation where the method appears between an object and it’s parameters. The arithmetic operators all fit here.

Postfix (also suffix):

That notation is used when the method follows an object and receives no parameters. For example, you can write list tail, and that’s postfix notation.

You can chain infix notation calls without problem, as long as no method is curried. For example, I like to use the following style:

(list
 filter (...)
 map (...)
 mkString ", "
)

That’s the same thing as:

list filter (...) map (...) mkString ", "

Now, why am I using parenthesis here, if filter and map take a single parameter? It’s because I’m passing anonymous functions to them. I can’t mix anonymous functions definitions with infix style because I need a boundary for the end of my anonymous function. Also, the parameter definition of the anonymous function might be interpreted as the last parameter to the infix method.

You can use infix with multiple parameters:

string substring (start, end) map (_ toInt) mkString ("<", ", ", ">")

Curried functions are hard to use with infix notation. The folding functions are a clear example of that:

(0 /: list) ((cnt, string) => cnt + string.size)
(list foldLeft 0) ((cnt, string) => cnt + string.size)

You need to use parenthesis outside the infix call. I’m not sure the exact rules at play here.

Now, let’s talk about postfix. Postfix can be hard to use, because it can never be used anywhere except the end of an expression. For example, you can’t do the following:

 list tail map (...)

Because tail does not appear at the end of the expression. You can’t do this either:

 list tail length

You could use infix notation by using parenthesis to mark end of expressions:

 (list tail) map (...)
 (list tail) length

Note that postfix notation is discouraged because it may be unsafe.

I hope this has cleared all the doubts. If not, just drop a comment and I’ll see what I can do to improve it.

Leave a Comment