Odersky’s statement is valid and significant, but some people don’t understand what he meant.
Let's say that in Java you have a Foo class with the f method:
class Foo { int f() { } }
You can write a method that takes Foo and calls f on it:
void g(Foo foo) { foo.f(); }
Perhaps there is a SubFoo class that extends Foo; g is also working on this. There may be a whole set of classes, inherited or interface, that share the fact that they can be used with g.
Now make this method f static:
class Foo { static int f() { } }
Is it possible to use this new Foo with g, maybe so?
g(Foo); // No, this is nonsense.
darn. Well, let it change the signature of g so that we can pass Foo to it and call it f.
O'ops - we cannot. We cannot pass a reference to Foo because Foo is not an instance of any class . Some people commenting here are confused by the fact that there is a class object corresponding to Foo, but as Sotirios tried to explain, this class object does not have a method f, and Foo is not an instance of this class. Foo is not an example of anything; it is not an object at all. The class object for Foo is an instance of the Class class that contains information about Foo (think of it as the internal Wikipedia page of Foo) and is completely irrelevant to the discussion. Wikipedia page for “tiger” is not a tiger.
In Java, “primitives,” such as 3 and “x,” are not objects. These are objects in Scala. For performance, your program will use JVM primitives for 3 and "x" whenever possible at runtime, but at the level you code, they really are objects. The fact that they are not objects in Java has rather adverse consequences for anyone trying to write code that processes all types of data — you must have special logic and additional methods to cover primitives. If you have ever seen or written such code, you know that it is terrible. The Oder affirmation is not "purism"; far from him.
In Scala, there is no part of the run-time data that is not an object, and there is no way to call methods that are not an object. In Java, none of these statements are true; Java is a partially object oriented language. In Java, there are things that are not objects, and there are methods that are not related to objects.
Scala newbies often think of object Foo as some kind of weird replacement for Java statics, but that you need to get through quickly. Instead, think of Java static methods as non-OO warts and Scala object Foo { ... } as something like this:
class SomeHiddenClass { ... } val Foo = new SomeHiddenClass
Here, Foo is a value, not a type, and it really is an object. It can be passed to the method. It can extend some other classes. For instance:
abstract class AbFoo { def f:Int } object Foo extends AbFoo { def f = 2 }
Now finally you can say
g(Foo)
It is true that the “companion object” for the class is a good place to host methods and data other than the instance for the class. But this companion object is an object, so the usual rules and possibilities apply.
The fact that in Java you put such methods on non-objects, restricting their use is a commitment, not a function. This, of course, is not OO.