Tag Archives: java

Validation in Octarine

A Record  in Octarine is a heterogeneous map, whose keys carry type information about their values. The only type guarantee you get is that if a Record  contains a Key<T> , then the value pointed to by that key will be of type T:

Some additional safety can be given by validating a Record  against a Schema<T> . If the validation is successful, a Valid<T>  can be obtained, which is a Record  ornamented with a type tag linking it to the schema that validated it. You can then enlist the help of the compiler in ensuring that code that will only work with a Valid<T>  is only ever passed a Valid<T> .

Here’s how it works:

The Person  interface here is never instantiated. It has two purposes:

  1. To act as a holder for the Key s and Schema  associated with Person s
  2. To be used as a type tag identifying Record s that have passed validation as instances of  Valid<Person>

The Schema<Person>  is created from a lambda expression that consumes a record and a consumer of validation errors, to which it can send strings describing any errors that it detects. In the example above, we test for the presence of two keys, and apply an additional test to the value of the “age” key.

You can call Validation::isValid  to find out whether validation has succeeded, and Validation::validationErrors  to get a list of all the validation errors that have been detected. Only if the list of validation errors is empty will Validation::get  return a Valid<T> ; otherwise a RecordValidationException  will be thrown.

The tests for the presence of mandatory keys are a bit cumbersome, so you can use a KeySet  to check that all the keys belonging to Person  are present:

Obviously, the compiler can’t guarantee that validation will succeed, since the tests carried out by the schema are only executed at runtime. However, you can subsequently guarantee that other code will only be passed a record that has been validated, by requiring a type of Valid<T>  rather than just a plain Record . This is how Octarine’s validation provides a bridge between the type-unsafe world of external data, and the type-safe world of your program’s domain model.

Enriching is Easy

Today I’d like to talk about a pattern that as far as I know is unique to Java 8. It makes use of the unusual way Java 8 implements lambdas as single-method interfaces, and the support for default methods in interfaces, to produce what I call “enriched lambdas”.

Here’s a simple example: a “Logged function” that logs every call that is made to it:

Now we can add the logging behaviour to any function by assigning or casting it to LoggedFunction rather than Function:

How does this work? LoggedFunction has only one method without a default implementation, so any lambda that matches the signature of this method can be cast to an instance of LoggedFunction. Instead of overriding the “apply” method of LoggedFunction, the lambda will override the “applyLogged” method, which the default “apply” method implementation delegates to.

Octarine uses this pattern in a variety of ways, notably to build up Schemas, Serialisers and Deserialisers from single lambda expressions:

In this case, the unimplemented method is used to configure the object, and all other methods (with their default implementations) use this method to obtain their configuration.

This pattern is similar in some respects to the “enrich my library” pattern in Scala, which uses implicits – it provides a safe and convenient way to “upcast” simple lambdas to objects with enriched behaviour.