Compilation order?

for this statement:

a expr b

will it be complained as:

a.expr(b)

or

a(expr(b))

thanks

I asked this question b/c the cases below:

scala> List(1,2,3) filter (_ > 2)
val res31: List[Int] = List(3)

scala> throw new Exception
java.lang.Exception
  ... 32 elided

the former ie explained as a.expr(b)
while the latter is explained as a(expr(b))
so I was a bit confused.

In the first one, List(1,2,3) is an object, which has a method called filter, which accepts a function value, so it is of the form object.method(value).
In the second one, Exception is the name of a class, new is a special keyword that creates an instance of it, and new Exception is a value by itself:

scala> new Exception
val res0: Exception = java.lang.Exception

and throw is not an object with methods like List(1,2,3), but is a special language keyword. You can think of it as a “function” with side effects, if it helps:

scala> throw(new Exception)
java.lang.Exception
  ... 30 elided

so throw new Exception has the form function(value) (it’s not really a function but you can think of it that way). throw expressions actually have type Nothing:

scala> val ex = throw new Exception
java.lang.Exception
  ... 30 elided
                                                                                                                                       
scala> :t ex
Nothing

but throw expressions do not actually evaluate to anything. There is a bit of “mental gymnastics” going on. Here is an excerpt from “Programming in Scala 5th Edition”:

Throwing exceptions
Throwing an exception in Scala looks the same as in Java. You create an
exception object and then throw it with the throw keyword:

throw new IllegalArgumentException

Although it may seem somewhat paradoxical, in Scala, throw is an ex-
pression that has a result type. Here’s an example where result type matters:

def half(n: Int) =
  if n % 2 == 0 then
    n / 2
  else
    throw new RuntimeException("n must be even")

What happens here is that if n is even, half will return half of n . If n is
not even, an exception will be thrown before half can return anything at all.
Because of this, it is safe to treat a thrown exception as any kind of value
whatsoever. Any context that tries to use the return from a throw will never
get to do so, and thus no harm will come.
Technically, an exception throw has type Nothing . You can use a throw
as an expression even though it will never actually evaluate to anything. This
little bit of technical gymnastics might sound weird, but is frequently useful
in cases like the previous example. One branch of an if computes a value,
while the other throws an exception and computes Nothing . The type of
the whole if expression is then the type of that branch which does compute
something.

1 Like