using Terse
@types Animal > (
Cat(lives::Int = 9),
@mutable Dog(@const(name::String); pointy_ears::Bool = true)
)
Cat(), Dog("Rex")(Cat(lives=9), Dog(name="Rex", pointy_ears=true))
Julia has several macros for cutting boilerplate out of struct definitions. This page compares Terse.jl with Base.@kwdef, QuickTypes.jl, Parameters.jl, and ConcreteStructs.jl.
| Feature | @kwdef |
QuickTypes | Parameters | ConcreteStructs | Terse |
|---|---|---|---|---|---|
| Concise syntax | ✓ | ✓ | ✓ | ||
| Default values | ✓ | ✓ | ✓ | ✓ | |
| Keyword constructors | ✓ | ✓ | ✓ | ✓ | |
| Mutable structs | ✓ | ✓ | ✓ | ✓ | ✓ |
| Parametric types | ✓ | ✓ | ✓ | ✓ ᵃ | ✓ |
| Abstract supertypes | ✓ | ||||
| Whole hierarchy at once | ✓ | ||||
| Nested hierarchies | ✓ | ||||
| Per-type mutability | ✓ | ||||
| Const fields | ✓ | ||||
| Computed constructors | ✓ | ||||
| Hidden fields | ✓ | ||||
| Escape hatch | ✓ | ||||
| Source lines | — | ~540 | ~670 | ~245 | ~280 |
| Dependencies | — | 2 ᵇ | 2 ᶜ | 0 | 0 |
ᵃ type parameters inferred automatically
ᵇ ConstructionBase, MacroTools
ᶜ OrderedCollections, UnPack
The same hierarchy written five ways: an abstract Animal with a Cat (default lives = 9) and a mutable Dog with a const name field and a keyword argument.
One type at a time; @qmutable has no const field support, so Dog falls back to plain Julia.
Block syntax; no const field support in @with_kw.
No extra dependencies; no const field support in @kwdef.
@concrete infers type parameters from untyped fields rather than generating constructors, so defaults, keyword arguments, and const fields are all written by hand.