tags:

views:

560

answers:

2

In Scala, why can I omit the dot and brakets in T m 0 (instead of T.m(0)):

scala> object T { def m(i:Int) = 0 == i }
defined module T

scala> T m 0
res19: Boolean = true

But why can't I omit the brakets in n(0):

scala> def n(i:Int) = 0 == i
n: (Int)Boolean

scala> n 0
<console>:1: error: ';' expected but integer literal found.
       n 0
         ^
+3  A: 

I believe the operator syntax style works only when you've got an explicit object on the left-hand side. The syntax is intended to let you express "operand operator operand" style operations in a natural way.

Rob H
I don't know what you mean by explicit object, but you can have pretty much anything that evaluates to an object on your left side, right? (...left?)
André Laszlo
+6  A: 

The former example, T m 0, is an example of "operator notation". Scala has three types of operator notations, prefix (called unary), infix and postfix. Let's see examples of all three in action here:

class MyByte(val n : Int) {
  require(n >= 0 && n <= 255)
  def unary_! = new MyByte(n ^ 0xff)
  def +(m : MyByte) = new MyByte(n + m.n)
  def bits = (Math.log(n) / Math.log(2) + 1).toInt
  override def toString = "0" * (8 - bits) + n.toBinaryString
}

An here it is in use:

scala> val a = new MyByte(5)
a: MyByte = 00000101

scala> val b = new MyByte(10)
b: MyByte = 00001010

scala> ! a  // Prefix/Unary
res58: MyByte = 11111010

scala> a + b  // Infix
res59: MyByte = 00001111

scala> b bits  // Postfix
res60: Int = 4

While infix and postfix notations accept any valid Scala identifier, though there is talk of restricting postfix notation, only four identifiers can be used as prefix: ~, !, - and +.

Now, when you try "m 0", Scala discards it being a unary operator, on the grounds of not being a valid one (~, !, - and +). It finds that "m" is a valid object -- it is a function, not a method, and all functions are objects.

As "0" is not a valid Scala identifier, it cannot be neither an infix nor a postfix operator. Therefore, Scala complains that it expected ";" -- which would separate two (almost) valid expressions: "m" and "0". If you inserted it, then it would complain that m requires either an argument, or, failing that, a "_" to turn it into a partially applied function.

Daniel