Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

adt4j - Algebraic Data Types for Java

This library implements Algebraic Data Types for Java.
ADT4J provides annotation processor for @GenerateValueClassForVisitor annotation.
ADT4J generates new class for each @GenerateValueClassForVisitor annotation.

It allows you to easily define custom data types. Like this:

// Define Expression data type
@WrapsGeneratedValueClass(visitor = ExpressionVisitor.class)
// ExpressionBase class will be automatically generated by annotation processor
// You can use any other name instead of ExpressionBase, like VeryLongNameThatYouShouldNeverActuallyUse
class Expression extends ExpressionBase {
  public static void main(String[] args) {
    // Static constructor methods are automatically generated for Expression class
    Expression e = mul(sum(lit(5), lit(1)), lit(2));

    // Reasonable default toString implementation is provided:
    System.out.println(e + " = " + e.eval());

  // This is the required boilerplate for wrapper-class
  Expression(ExpressionBase base) {

  // Example of "pattern-matching"
  int eval() {
    return accept(new ExpressionVisitor<Integer>() {
      Integer lit(int i) {
        return i;
      Integer sum(Expression e1, Expression e2) {
        return e1.eval() + e2.eval();
      Integer mul(Expression e1, Expression e2) {
        return e1.eval() * e2.eval();

  // Actual data-type definition
  // Data type is recursive. No special treatment of recursive definition is required.
  @GenerateValueClassForVisitor(wrapperClass = Expression.class)
  interface ExpressionVisitor<R> {
    @GeneratePredicate(name = "isLiteral");
    R lit(int i);

    R sum(@Getter(name = "leftOperand") Expression e1, @Getter(name = "rightOperand") Expression e2);
    R mul(@Getter(name = "leftOperand") Expression e1, @Getter(name = "rightOperand") Expression e2);



  • Support recursive data types
  • Generate hashCode, equals and toString implementations with value semantics
  • Generate predicates, getters and "updaters" with additional annotations
  • Fully customizable API: custom names and access levels for generated methods
  • Optionally generate Comparable implementation with precise compile-time type-check if it is possible
  • Optionally generate serializable classes with precise compile-time type-check if it is possible
  • Sensible error messages
  • Support generated class extention through standard Java's inheritance.
  • Reasonably fast

Known Issues


ADT4J is under BSD 3-clause license.


Flattr this git repo


Use maven dependency to use ADT4J:


You can use adt4j-shaded artifact to simplify deployment and to avoid dependencies' conflicts. adt4j-shaded has no dependencies and does not pollute classpath. All java-packages provided by adt4j-shaded are rooted at com.github.sviperll.adt4j package.



See NEWS file.


See Tutorial


$ git clone
$ cd adt4j
$ mvn test

Check for errors and warnings.

ADT4J is built to be compatible with Java 7. See universal-maven-parent project's documentation for instructions about building projects compatible with JDK7.