This post might contain provocative statements. Reader is advised to not to get provoked too easily 🙂



Tl; Dr? Skip to summary.

Chapter 1. Innocent and evil

This is a singleton object Foo in Scala:

object Foo

Poor singleton object probably never meant to be evil nor to hurt any one. I mean look at it. So simple, cute and obvious. What harm can it be to any one and how could ever hate it?

Well, it turns out that if you let that cute little object to grow carelessly it can go postal on you and your code. And if that isn’t disturbing enough, it can do it in so very subtle ways…

I am referring to a singleton pattern in here. It can be real annoyance if it wasn’t carefully planned beforehand. I do not bother to repeat the sins of the singleton pattern again. They are documented thoroughly else where. However, the singleton pattern plays central role in this post so the reader is advised to be well acquainted with it before proceeding.

Chapter 2. Hard to master

So, your favourite programming language has a built-in anti-pattern(1. And quite prominently so. Now how cool is that?

In world of Java this is not usually an issue for veteran programmers. They’ve learned how to avoid singleton pattern or at least have a good understanding what are the implications in case they choose use it. This is not to say that singletons are pure evil (although, they come pretty close). Singletons do have few legitimate use cases but those are rare.

This certainly doesn’t sound good. One needs to have a veteran skill set to avoid shooting him self. And what makes shooting easier than bundling it with the language using single keyword: object…

1) Not really, but almost.



Chapter 4. The malice

At what point singleton object becomes evil? Obviously the young singleton object Foo introduced earlier is harmless. Let’s have an example:

object EvilFoo { var answer = 42 } object GoodFoo { val answer = 42 }

It is the statefulness/mutability which makes the singleton object evil. And the evilness can creep in almost silently:

class Person(var name: String) // mutable! object Prefect { val person = new Person("Ix") // ouch! }

Prefect object looks immutable but unfortunately it is hard wired to mutable instance of Person. You will shoot your self in the foot eventually by writing this kind of code.

Chapter 5. Avoidance

Fortunately there is a simple trick to fix any broken singleton object: replace every val and var with def. This should apply to all transient dependencies, in case the object imports or extends other objects. This way you are effectively making the singleton object to be strictly immutable, functional and stateless.

In fact you should always use def instead of val. Why? Because using val makes you responsible that the object stored in val is strictly immutable. And an object is strictly immutable only when all it’s transitive dependencies are also (strictly) immutable. You will sleep your nights better when you’ll stick to this rule, trust me.

Do we have something ground breaking here? No, you’ve probably used this concept long before you even knew it by name. The formulation is known as utility pattern. Java folks usually talk about utility classes. Perhaps we should use term utility object in Scala when a singleton object conforms to utility pattern.

Sounds too good to be true? Well, it is true but there are some things you should be aware of. The performance is obvious one: returning a new instance on every invocation can be expensive, especially on complex objects. Another case is when a reference identity is required, but fortunately this is extremely rarely needed. And finally, somewhat related to previous: given the same input, each instance returned by the method should usually be equal to each other. In other words the method should be functional. This perhaps the only pitfall when using def. In general, following should hold, no matter what:

Foo.f() == Foo.f() // must evaluate to true always

Let’s try to fix the Prefect object we saw earlier:

class Person(var name: String) // mutable! object Prefect { def person = new Person("Ix") // stateless! }

The Person instances are still mutable but that is not relevant in here: the singleton object Prefect is strictly immutable and stateless; no hard wired dependency to mutable person instance. However, the Prefect is not fully functional, why?

As mentioned earlier the policy should apply to all transient dependencies:

object Foo extends Bar { import Baz._ def answer = ... }

You should make sure that Bar and Baz are also functional, stateless and immutable. In best case you have a full control over the classes and you can enforce the same policy on them.

As you can see, there is lot to keep in mind when playing with utility objects.

Chapter 6. A better way

But where does this leave us with singletons? Well, obviously singletons are pretty nasty so we should try something else:

class FriendlyFoo { var answer = 42 }

That looks like a normal class but what if we used it like this:

object MyApp { def main(args: Array[String]) { val friedlyFoo = new FriendlyFoo() } }

For all practical purposes the friendlyFoo is a singleton in here: we created only single instance of it. But what is even more important is that you are now in control: you will decide when the instance is created. The most descriptive name I could find for this pattern is managed single instance.

In broader sense, it is all about controlling instance life cycle. Some examples are: application, session, request and transaction. Dependency injection (DI) is usually a great help when it comes to life cycle management. See my previous post for more about dependency injection.

Chapter 7. The singleton

But what if you really need a singleton, is there anything we might do? Well, there are few conventions which might help.

First, make sure that the object is not a companion object nor a package object. Secondly, make it stand out clearly, for example, by using a Singleton suffix:

object MySingleton { var myCounter = 0 }

There is not much else we can do.

Chapter 8. The rage

Singleton objects, utility objects, managed single instances, companion objects, package objects and singletons. Do we have a small scale in disaster here?

Scala makes singletons easy, for better or worse. History has shown to us that singletons are easily seen as a golden hammer and overused, especially by novice programmers. Then there is the utility pattern which is also realized by using singleton object. So what we have is a situation where the same language construct is used to implement two very different patterns. And it certainly doesn’t help that the utility pattern and singleton pattern are almost impossible to distinguish from each other without explicit labelling in Scala.

This leaves the burden to a programmer to keep these two patterns from mixing accidentally.

So yes, we have a disaster here: singletons are way too easy, unintentional singleton is mostly a matter of time (well, not for [most] veteran programmers) and there is no language level support to enforce stateless objects. This design is against the very foundation of Scala to encourage functional programming and immutability. It might be even better for programmer to avoid object construct unless there is a very clear use case for it.

When comparing to Java, does Scala actually make it easier or harder to design functionally correct programs when considering singleton objects? It might be a worth meditating this question a moment or two.

Chapter 9. Fixing the object

But does it really need fixing or is there actually anything to fix? Scala is designed not to constraint the programmer. And this is nice principle in general. It is the coder who should have the responsibility. Trying to push the responsibility toward programming language doesn’t sound good. So it is not about the language but how you use it. Right?

But perhaps there is something we can try. Adding a new language keyword, such as “stateless”, which would be akin to object construct except with enforcement of statelessness and immutability might be a good start. The simplest version might allow just using def and extending/importing other stateless objects. Anyway, I am not an expert on this matter. Just a thought off the top of my head.

In mean time, one possibility is to attack the issue with tools. Having a compiler plug-in or a static code analysis tool to highlight sore points in code would be quite welcome. It should be relatively easy to detect certain features such as vars in objects, for example.

It would be interesting to know if there are ongoing efforts to to solve this problem at language level.

Chapter 10. Summary

Object construct in Scala is typically used to implement utility and singleton pattern. Singleton is generally regarded an anti-pattern while most singleton objects in Scala are intended to implement the utility pattern. This leads to a situation where programmer can turn an utility object to a singleton unintentionally since these two patterns are nearly indistinguishable without explicit labelling. There is no immediate solution to this problem. For now, one reasonable option is to have a set of conventions to avoid mixing the two patterns accidentally.

For singleton objects in general:

Must implement utility pattern (aka utility object): strictly immutable, functional and stateless.

Prefer def at all times instead of val. By using val you are responsible that stored value is strictly immutable. You might need to check that function result type implements equality correctly when using def. This is usually required for object to be functional.

Make sure that all transient dependencies are also utility objects.

It might be even good to avoid object construct unless you have solid reasoning for using it.

For objects implementing singleton pattern:

Avoid: managed single instances are better choice in 99.9 % of cases.

When a true singleton is needed it must not be a companion nor a package object. Label code visibly, for example use “Singleton” suffix in name.

With these guidelines you should be able to avoid some basic mistakes and, how knows, even bigger disasters.

There are other patterns and idioms which could benefit from similar analysis in singleton object context. And in general, analysis of object construct usage in various Scala projects might yield some interesting results.