Understanding the Derive Macro
The @derive macro comes from Rust’s derive macro, which is a way to automatically implement traits for data types. In Rust, a trait is a set of interface functions that a type must implement. The derive macro allows you to automatically implement these functions for your data types.
In Julia, the trait is loosely defined as a set of functions that a type implements. The @derive macro in Moshi.jl is similar to Rust’s derive macro, but it is more flexible and dynamic. It gives you a unified way to derive trait functions for your data types, whether they are algebraic data types (ADTs) or Julia structs.
One example of previous packages is the AutoHashEquals package. The @auto_hash_equals macro automatically derives the hash, == and isequal functions for your Julia structs. In @derive macro, this is equivalent to:
@derive MyType[Hash, Eq]Unlike AutoHashEquals, the @derive macro is naturally extensible to other traits. Similar to Rust’s derive macro, you can define how other traits are derived for your data types.
How to Use
Section titled “How to Use”The @derive macro is used to derive traits for your data types. You can use it to automatically implement functions for your data types.
using Moshi.Derive: @derive
struct Foo x::Int y::Intend
@derive Foo[Hash, Eq, Show]In this example, we define a struct Foo with two fields x and y. We then use the @derive macro to derive the Hash, Eq, and Show traits for the Foo struct. This is equivalent to the following code:
Base.hash(f::Foo, h::UInt) = hash(f.x, hash(f.y, h))Base.==(a::Foo, b::Foo) = a.x == b.x && a.y == b.yBase.isequal(a::Foo, b::Foo) = isequal(a.x, b.x) && isequal(a.y, b.y)Base.show(io::IO, f::Foo) = print(io, "Foo($(f.x), $(f.y))")