API

Macros

@types

@types AbstractType
@types [mutable] ConcreteType(pos_fields...; kw_fields...)
@types [mutable] ConcreteType(pos_fields...; kw_fields...) <: SuperType
@types [mutable] ConcreteType(args...) = new(field::T = expr, ...)
@types [mutable] AbstractType > (Subtype1(fields...), Subtype2(fields...))
@types [mutable] AbstractType{T} > (Subtype1{T}(fields...), Subtype2{T, S}(fields...))

Define abstract types, concrete structs, or full type hierarchies in one expression.

  • mutable makes all generated concrete structs mutable.
  • @mutable SubType(...) makes an individual subtype mutable within a hierarchy.
  • @const(field::T) marks a field as const within a @mutable or mutable type.
  • Fields with default values (field::T = val) generate inner constructors for both positional-with-defaults and keyword argument construction.
  • Use ; to separate positional fields from keyword-only fields, generating a single constructor that mirrors the exact positional/keyword split you specify.
  • Subtypes can themselves use > to define nested hierarchies.
  • Parentheses decide abstract vs. concrete: a bare name (Worm) declares an abstract type, while empty parentheses (Worm(), Worm{T}()) declare a zero-field concrete struct.
  • Every subtype of a parametric parent must declare the parent’s type parameters (Mollusc{T}, not Mollusc).
  • @hide(field::T) suppresses a field from the auto-generated show method.
  • Computed constructors (Name(args...) = new(field::T = expr, ...)) let you define struct fields that differ from the constructor arguments. Each new(...) argument must be field = expr or field::T = expr, where expr computes the stored value from the constructor args.
  • @esc(expr) splices arbitrary code (e.g. interface methods) into the hierarchy output.
  • Each concrete subtype gets an auto-generated docstring showing its hierarchy path and constructor signature (e.g. `“Animal >

Dog(name::String)“`). Place a string literal immediately before a subtype entry to override it with a custom docstring.

Examples

@types Animal

@types Cat(lives::Int)

@types Dog(name::String) <: Animal

@types mutable Counter(n::Int = 0)

@types Server(host::String; port::Int = 8080, timeout::Int = 30)

@types Animal > (
    Cat(lives::Int),
    Dog(name::String)
)

@types Animal > (
    Cat(lives::Int = 9),
    @mutable Dog(@const(name::String), legs::Int)
)

# Custom docstrings: place a string before the entry to override the auto-generated doc
@types Animal > (
    "A feline with a fixed number of lives.",
    Cat(lives::Int = 9),
    Dog(name::String),  # auto-doc: "Animal > 
Dog(name::String)"
)

# Computed constructor: struct fields differ from constructor args
@types Point(x, y) = new(r::Float64 = hypot(x, y), θ::Float64 = atan(y, x))

@types Animal{T} > (
    Cat{T}(lives::Int, family::T),
    Dog{T, S <: AbstractString}(name::S, family::T),
    Invertebrate{T} > (
        Worm{T}(),                  # zero-field concrete struct
        Mollusc{T},                 # abstract type Mollusc{T} <: Invertebrate{T}
        Insect{T, I <: Integer}(legs::I, family::T)
    )
)