Optional Parameters

The billion dollar mistake has been committed already. No going back. But it is not necessary to keep repeating it. Oh, I am talking about the infamous null.

A real solution to avert the issues surrounding null is to completely avoid using it in your code, and replace direct use of null with some sort of nullable container, such as the Option[A] in Scala. You could go even as far and enforce not to use null anywhere in your code via Scalastyle or other linters.

In Scala, it is pretty common to pass and return1 Option. For instance …

case class Email(
	subject: String,
	body: String,
	attachment: Option[Attachment]
)

object Email {
	def apply(subject: String, body: String): Email =
		new Email(subject, string, attachment = None)
}

In the above code, attachment may optionally be passed to create an instance of Email. Another way, a bad one, to achieve the same with sufficient safety around null is:

# This is bad! Don't do it!
class Email(
	val subject: String,
	val body: String,
	attached: Attachment
) {
	val attachment: Option[Attachment] = Option(attached)
}

// calling code
new Email("hello", "world", null)

The above code does not use Option but directly use null, which is wrapped with an Option inside the Email class. While this provides safety net around null, it is just a bad way.

Introducing null in one place potentially causes loss in the strictness of types. The null may be direct value as shown in the example above. Or a runtime value passed down via chain of calls to a variable passed to Email constructor, which makes it harder to reason about. Besides, did you notice I had to change the original case class to a regular class2?

Let us switch gears. Java too has a nullable container - the infamous3 Optional<T>.

In the Java realm, returning Optional from methods is acceptable. Passing Optional as parameters is not.

IntelliJ warns such cases via its inspections. opt.jpg

While you can suppress inspections at your will, that is the not point. It is recommended not to pass Optional as parameters. Even by Java experts.

opt2.jpg

I was not able to find a compelling reason behind such a recommendation, which is in contrast to Scala. Almost every link or material I came across was about to disabling4 the inspection to silence IntelliJ from throwing the warning.

However, I came across a couple of things where were better out of the lot. But not compelling.

On a larger scale, I prefer to align with the community - practices, guidelines and conventions. And temper only specific things to cater to my taste/style. For a good reason. In the case of this warning about using Optional parameters, I have mixed feelings. Neither do I want to disable the inspection in IntelliJ because IntelliJ team is way smarter than us, and I hope they added it for a reason. Nor do I want litter my code with SuppressWarnings4.

Given that the IntelliJ inspection is a tooling aspect and general advice from elders, I might consider disabling it after all.


  1. The case class fields are getters and hence are returning Option. The constructor as written above is the argument. So, passing and returning. ↩︎

  2. Similar handling is not possible using case class; at least not in a clean way. You might end up having redundant fields breaking invariant on attachment. Or some unnecessarily convoluted code. ↩︎

  3. Yes, infamous. Because it is poorly implemented. I might have to write about it in separate post. Let me not digress. ↩︎

  4. In the worst case you have to suppress the warning, use @SuppressWarnings("OptionalUsedAsFieldOrParameterType") instead of disabling the inspection for all cases. ↩︎ ↩︎

  5. There are definitely some elite / esoteric Java code out there that fall in the category of functional thinking, if not really written using functional techniques. ↩︎