Skip to content

Enumerations

Jonathan edited this page Feb 25, 2018 · 4 revisions
enum Color {
    RED, GREEN, BLUE
}

Also Firefly enums may have parameters:

enum Color(val rgb: Int) {
    RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF)
}

And generic types:

enum Option<T> {
    Some(val value: T),
    None
}

Java compatibility

Firefly enums are compiled in @Compat mode by default, this means that the compiler should transform the declaration to be more compatible with Java without losing Type safety, breaking semantics, and losing other important things, this declaration:

enum Option<T> {
    Some(val value: T),
    None
}

Gets compiled into something like:

@Enum
public class Option<T> {
    Option() {}
    
    public static Some<T> some(T value) {
        return new Some<>(value);
    }
    
    public static None none() {
        return None.INSTANCE;
    }
}

@EConst(owner = Option.class, const = "Some")
public class Some<T> extends Option<T> {
    private final T value;

    Some(T value) {
        this.value = value;
    }

    public T getValue() {
        return this.value;
    }

    public int hashCode() { 
        return Objects.hashCode(this.getValue()); 
    }

    public Object equals(Object o) {
        return o instanceof Some<?> && Objects.equals(this.getValue(), ((Some) o).getValue());
    }

}

@EConst(owner = Option.class, const = "None")
public class None extends Option {
    static final None INSTANCE = new None();
    private None() {}

    public int hashCode() { 
        return super.hashCode(); 
    }

    public Object equals(Object o) {
        return o instanceof None && this == o;
    }
}

Option still type safe from Java context, but lack some enum methods like name, values, ordinal, we will discuss it later.

But we have another compilation mode, the @Conservative, this mode conserves the original structure as much as possible, but have too much disadvantages:

  • Generated code is valid at bytecode level and from Java context, but things get a bit weird...
  • There is factory methods that creates new enum instances, this breaks Java enum semantics and have an unexpected behavior.
  • ordinal always return the same number for Some instances, regardless wrapped value.
  • values method will return Some(None) (yes) and None.
  • Some will be available as enum constant, but the value is Some(None).
  • Object.equals is not implemented
  • Object.hashCode is not implemented

Note that @Conservative is annotated with @Warning, so compiler will warn about use of @Conservative. Conservative should only be used when really needed.

Kores have a test with a similar code that will be generated in this mode:

Clone this wiki locally