Why doesn't Scala have static members inside a class?

I know you can define them indirectly achieve something similar with companion objects but I am wondering why as a language design were statics dropped out of class definitions.


Solution 1:

The O in OO stands for "Object", not class. Being object-oriented is all about the objects, or the instances (if you prefer)

Statics don't belong to an object, they can't be inherited, they don't take part in polymorphism. Simply put, statics aren't object-oriented.

Scala, on the other hand, is object oriented. Far more so than Java, which tried particularly hard to behave like C++, in order to attract developers from that language.

They are a hack, invented by C++, which was seeking to bridge the worlds of procedural and OO programming, and which needed to be backwardly compatible with C. It also admitted primitives for similar reasons.

Scala drops statics, and primitives, because they're a relic from a time when ex-procedural developers needed to be placated. These things have no place in any well-designed language that wishes to describe itself as object-oriented.


Concerning why it's important to by truly OO, I'm going to shamelessly copy and paste this snippet from Bill Venners on the mailing list:

The way I look at it, though, is that singleton objects allow you to do the static things where they are needed in a very concise way, but also benefit from inheritance when you need to. One example is it is easier to test the static parts of your program, because you can make traits that model those parts and use the traits everywhere. Then in the production program use a singleton object implementations of those traits, but in tests use mock instances.

Couldn't have put it better myself!

So if you want to create just one of something, then both statics and singletons can do the job. But if you want that one thing to inherit behaviour from somewhere, then statics won't help you.

In my experience, you tend to use that ability far more than you'd have originally thought, especially after you've used Scala for a while.

Solution 2:

I also posted this question on scala users google group and Bill Venners one of the authors of "Programming in scala" reply had some insights.

Take a look at this: https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/6vZJgi42TIMJ and https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/oTrLFtwGjpEJ

Here is an excerpt:

I think one goal was simply to be simpler, by having every value be an object, every operation a method call. Java's statics and primitives are special cases, which makes the language more "complicated" in some sense.

But another big one I think is to have something you can map Java's statics to in Scala (because Scala needed some construct that mapped to Java's statics for interop), but that benefits from OO inheritance/polymorphism. Singleton objects are real objects. They can extend a superclass or mix in traits and be passed around as such, yet they are also "static" in nature. That turns out to be very handy in practice.

Also take a look at this interview with Martin Odersky (scroll down to Object-oriented innovations in Scala section) http://www.artima.com/scalazine/articles/goals_of_scala.html

Here is an excerpt:

First, we wanted to be a pure object-oriented language, where every value is an object, every operation is a method call, and every variable is a member of some object. So we didn't want statics, but we needed something to replace them, so we created the construct of singleton objects. But even singleton objects are still global structures. So the challenge was to use them as little as possible, because when you have a global structure you can't change it anymore. You can't instantiate it. It's very hard to test. It's very hard to modify it in any way.

To Summarize:

From a functional programming perspective static members are generally considered bad (see this post by Gilad Bracha - the father of java generics. It mainly has to do with side effects because of global state). But scala had to find a way to be interoperable with Java (so it had to support statics) and to minimize (although not totally avoid) global states that is created because of statics, scala decided to isolate them into companion objects.

Companion objects also have the benefit of being extensible, ie. take advantage of inheritance and mixin composition (separate from emulating static functionality for interop).

Solution 3:

These are the things that pop into my head when I think about how statics could complicate things:

1) Inheritance as well as polymorphism would require special rules. Here is an example:

// This is Java
public class A {
  public static int f() {
    return 10;
  }
}

public class B extends A {
  public static int f() {
    return 5;
  }
}

public class Main {
  public static void main(String[] args) {
    A a = new A();
    System.out.println(a.f());
    B b = new B();
    System.out.println(b.f());
    A ba = new B();
    System.out.println(ba.f());
   }
}

If you are 100% sure about what gets printed out, good for you. The rest of us can safely rely on mighty tools like @Override annotation, which is of course optional and the friendly "The static method f() from the type A should be accessed in a static way" warning. This leads us to

2) The "static way" of accessing stuff is a further special rule, which complicates things.

3) Static members cannot be abstract. I guess you can't have everything, right?

And again, these are just things which came to my mind after I gave the matter some thought for a couple of minutes. I bet there are a bunch of other reasons, why statics just don't fit into the OO paradigm.