Avoid clever tricks

The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.
–Edsger Dijkstra

scalacoffee

Strongly-typed Java disaster prevention in Scala

For today’s entry on the weblog we take a short excursion down null- and validation-checking certain-disaster lane and emerge out the other side victorious.

I was writing some Scala code yesterday. Unfortunately it interfaces with Java code (ew! yeck! boo! hiss!) so almost immediately I became mired in null-checking everything constantly. I also had to check for valid values since some of my particular variables didn’t make sense unless they were in a specific range.

Since I shouldn’t show you that code, let’s just pretend like this is the code:

object InputValidator {

  def validateInput(customerComments: String, customerEmail: String, starRating: Int) = {
    require(customerComments != null && customerComments.length > 0 && customerComments.length < 1000)
    require(customerEmail != null && customerEmail.length > 0 && isValidEmail(customerEmail))
    require(starRating != null && starRating >= 1 && starRating < = 5)

    //add'l code elided
  }
  
  def processCustomerComments(customerComments: String) = {
    require(customerComments != null && customerComments.length > 0 && customerComments.length < 1000)
    //add'l code elided for example
  }
  
  def sendThankYouEmail(customerEmail: String) = {
    require(customerEmail != null && customerEmail.length > 0 && isValidEmail(customerEmail))
    //add'l code elided for example
  }
  
  // so on and so forth ... ad infinitum
  
}

There were many more methods than these. They were called from various places in the client/calling code. And this was simplifying and cleaning up the calling code quite a bit. But, since all the values were bare types like String and int, I was putting these require statements at the top of every method to make sure no accidental bullshit like a NullPointerException would happen.

Since that choice made my Scala code obviously suck hard, I next tried making all method parameters of type Option, but I was bothered by the conviction that I should not semantically convey to my clients that any of these were optional when all fields were required. It also didn’t solve the problem of the further valid length and value checking that needed to happen. Another approach I briefly considered was the PartialFunction one.

Unfortunately, neither solution solved another issue, which is that the code still would not be DRY. Any change in the accepted-valid input, like changing star rating to accept the values 1 to 10, would create a situation where I had to go back and change validation logic everywhere it appeared.

Then I had a new idea: tiny types!

Tiny types to the rescue!

Continue reading “Strongly-typed Java disaster prevention in Scala”

scala-logo-small

Prefer types over booleans

In a recent post I represented whether a TV was on or off as an enum in Java and case objects in Scala. Someone asked me why you would do either one when you could simply represent it as a boolean.

The same reasoning would seem to extend to any situation with two choices:

  1. Male/Female
  2. On/Off
  3. In/Out
  4. Active/Inactive
  5. Hot/Cold
  6. Light/Dark
  7. etc..

I have a rule:

prefer types over booleans

This post is about why.

Continue reading “Prefer types over booleans”

Why there aren’t enums in Scala

Why doesn’t Scala have enums like Java?

Java enums are a good solution for the wrong problem. Programmers who came to Java from C/C++ were sick of defining fixed sets of constants as integers and they reached for a solution that gave them the most obvious type-safe replacement. In other words, given an already-existing paradigm, they improved upon it, but they did not stop and rethink it.

You may not remember integer constants in C/C++. Let’s say a TV set had to have ON and OFF states. It would be represented somewhere as follows:

//C/C++
const int ON = 0;
const int OFF = 1;

And elsewhere:

private:
  int state = ON;

public:
 int getState() = {
   return state;
 }

“int getState?” But it should only return 0 or 1! There are no other states! We should not have ON/OFF represented with a type that allows for (generally) 2^32 states.

Given this state of affairs, Java’s language designers decided on the “enum” which looks like the following for the TV example:

enum TvState {
  ON, OFF
}
public class TV {

  private TVState state = TVState.OFF;

  public TvState getState() {
    return state;
  }
}

All of this makes perfect sense if fixed sets of integer constants has been your operating assumption for a number of years.

Except it doesn’t …