Skip to content

Commit

Permalink
New syntax for 0.2 version (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tortar authored Feb 9, 2024
1 parent 3c1af36 commit 36f11c1
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "MixedStructTypes"
uuid = "3d69f371-6fa5-5add-b11c-3293622cad62"
version = "0.1.6"
version = "0.2.0"

[deps]
ExprTools = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
Expand Down
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@

This package allows to pack multiple heterogeneous types in a single type.

Two macros implement different strategies to create a compact representation of the types: `@sum_struct_type`
and `@compact_struct_type`.
Two macros implement different strategies to create a compact representation of
the types: `@compact_structs` and `@sum_structs`.

Both work very similarly but there are some differences:

- `@compact_struct_type` is a bit faster;
- `@compact_structs` is a bit faster;

- `@sum_struct_type` is more memory efficient and allows to mix mutable and immutable structs where fields belonging to different structs can also have different types, it uses [SumTypes.jl](https://github.com/MasonProtter/SumTypes.jl) under the hood.
- `@sum_structs` is more memory efficient and allows to mix mutable and immutable structs where fields belonging to different structs can also have different types, it uses [SumTypes.jl](https://github.com/MasonProtter/SumTypes.jl) under the hood.

Even if there is only a unique type defined by these macros, you can access a symbol containing the
conceptual type of an instance with the function `kindof`.
Expand All @@ -24,19 +24,19 @@ julia> using MixedStructTypes

julia> abstract type AbstractA{X} end

julia> @sum_struct_type @kwdef A{X} <: AbstractA{X} begin
mutable struct B{X}
julia> @sum_structs A{X} <: AbstractA{X} begin
@kwdef mutable struct B{X}
a::Tuple{X, X} = (1,1)
b::Tuple{Float64, Float64} = (1.0, 1.0)
const c::Symbol = :s
end
mutable struct C
@kwdef mutable struct C
a::Tuple{Int, Int} = (2,2)
const c::Symbol = :q
d::Int32 = Int32(2)
e::Bool = false
end
struct D
@kwdef struct D
a::Tuple{Int, Int} = (3,3)
c::Symbol = :s
f::Char = 'p'
Expand Down Expand Up @@ -64,19 +64,20 @@ julia> abstract type AbstractE{X} end
julia> # as you can see, here, all structs are mutable
# and all shared fields in different structs have
# the same type
@compact_struct_type @kwdef E{X} <: AbstractE{X} begin
mutable struct F{X}

julia> @compact_structs E{X} <: AbstractE{X} begin
@kwdef mutable struct F{X}
a::Tuple{X, X} = (1,1)
b::Tuple{Float64, Float64} = (1.0, 1.0)
const c::Symbol = :s
end
mutable struct G{X}
@kwdef mutable struct G{X}
a::Tuple{X, X} = (2,2)
const c::Symbol = :q
d::Int32 = Int32(2)
e::Bool = false
end
mutable struct H{X}
@kwdef mutable struct H{X}
a::Tuple{X, X} = (3,3)
const c::Symbol = :s
f::Char = 'p'
Expand Down Expand Up @@ -121,4 +122,3 @@ julia> @btime sum(x.a[1] for x in $vec_a);
julia> @btime sum(x.a[1] for x in $vec_e);
2.938 ms (0 allocations: 0 bytes)
```

33 changes: 22 additions & 11 deletions src/CompactStructTypes.jl → src/CompactStructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@
struct Uninitialized end
const uninit = Uninitialized()

macro compact_struct_type(new_type, struct_defs = nothing)

if struct_defs === nothing
is_kwdef = true
new_type, struct_defs = new_type.args[end-1:end]
else
is_kwdef = false
end
"""
@compact_structs(type_definition, struct_definitions)
"""
macro compact_structs(new_type, struct_defs)

if new_type isa Expr && new_type.head == :(<:)
new_type, abstract_type = new_type.args
Expand All @@ -18,6 +14,21 @@ macro compact_struct_type(new_type, struct_defs = nothing)
end
structs_specs = decompose_struct_base(struct_defs)

structs_specs_new = []
is_kws = []
for x in structs_specs
v1 = @capture(x, @kwdef d_)
v1 == false && (v2 = @capture(x, Base.@kwdef d_))
if d == nothing
push!(structs_specs_new, x)
push!(is_kws, false)
else
push!(structs_specs_new, d)
push!(is_kws, true)
end
end
structs_specs = structs_specs_new

is_mutable = []
for x in structs_specs
push!(is_mutable, x.args[1])
Expand Down Expand Up @@ -53,7 +64,7 @@ macro compact_struct_type(new_type, struct_defs = nothing)
end))

expr_functions = []
for (struct_t, struct_f, struct_d) in zip(types_each, fields_each, default_each)
for (struct_t, struct_f, struct_d, is_kw) in zip(types_each, fields_each, default_each, is_kws)
struct_spec_n = retrieve_fields_names(struct_f)
struct_spec_n_d = [d != "#328723329" ? Expr(:kw, n, d) : (:($n))
for (n, d) in zip(struct_spec_n, struct_d)]
Expand Down Expand Up @@ -91,7 +102,7 @@ macro compact_struct_type(new_type, struct_defs = nothing)
return $(namify(new_type))($(f_inside_args...))
end
)
if is_kwdef
if is_kw
expr_function_kwargs = :(
function $(namify(struct_t))($f_params_kwargs)
return $(namify(new_type))($(f_inside_args...))
Expand All @@ -111,7 +122,7 @@ macro compact_struct_type(new_type, struct_defs = nothing)
end
end
)
if is_kwdef
if is_kw
expr_function_kwargs = :(
begin
function $(namify(struct_t))($f_params_kwargs_with_T) where {$(struct_t_p...)}
Expand Down
8 changes: 4 additions & 4 deletions src/MixedStructTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ using ExprTools
using MacroTools
using SumTypes

export @sum_struct_type
export @compact_struct_type
export @sum_structs
export @compact_structs
export kindof

function kindof end
function constructor end

include("SumStructTypes.jl")
include("CompactStructTypes.jl")
include("SumStructs.jl")
include("CompactStructs.jl")

end
33 changes: 22 additions & 11 deletions src/SumStructTypes.jl → src/SumStructs.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@

macro sum_struct_type(type, struct_defs = nothing)

if struct_defs === nothing
is_kwdef = true
type, struct_defs = type.args[end-1:end]
else
is_kwdef = false
end
"""
@sum_structs(type, struct_definitions)
"""
macro sum_structs(type, struct_defs)

struct_defs = [x for x in struct_defs.args if !(x isa LineNumberNode)]

struct_defs_new = []
is_kws = []
for x in struct_defs
v1 = @capture(x, @kwdef d_)
v1 == false && (v2 = @capture(x, Base.@kwdef d_))
if d == nothing
push!(struct_defs_new, x)
push!(is_kws, false)
else
push!(struct_defs_new, d)
push!(is_kws, true)
end
end
struct_defs = struct_defs_new

isnotmutable = all(!(d.args[1]) for d in struct_defs)

variants_types = []
Expand Down Expand Up @@ -124,7 +135,7 @@ macro sum_struct_type(type, struct_defs = nothing)

expr_constructors = []

for (fs, fd, t, h_t) in zip(fields_each, default_each, variants_types, hidden_struct_types)
for (fs, fd, t, h_t, is_kw) in zip(fields_each, default_each, variants_types, hidden_struct_types, is_kws)
f_d_n = retrieve_fields_names(fs, false)
f_d_n_t = retrieve_fields_names(fs, true)
c = @capture(t, t_n_{t_p__})
Expand All @@ -137,7 +148,7 @@ macro sum_struct_type(type, struct_defs = nothing)
end
)
c4 = :()
if is_kwdef
if is_kw
c4 = :(function $t($(f_params_kwargs)) where {$(t_p...)}
return $t($h_t($(f_d_n...)))
end
Expand All @@ -152,7 +163,7 @@ macro sum_struct_type(type, struct_defs = nothing)
end
)
c3 = :()
if is_kwdef
if is_kw
c3 = :(function $(namify(t))($(f_params_kwargs))
return $(namify(t))($(namify(h_t))($(f_d_n...)))
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
@compact_struct_type @kwdef E{X,Y} begin
mutable struct F{X}

@compact_structs E{X,Y} begin
@kwdef mutable struct F{X}
a::Tuple{X, X}
b::Tuple{Float64, Float64}
const c::Symbol
end
mutable struct G{X}
@kwdef mutable struct G{X}
a::Tuple{X, X}
d::Int32
e::Bool
const c::Symbol
end
mutable struct H{X,Y}
@kwdef mutable struct H{X,Y}
a::Tuple{X, X}
f::Y
g::Tuple{Complex, Complex}
const c::Symbol
end
end

@compact_struct_type @kwdef Animal2{T,N,J} begin
mutable struct Wolf2{T,N}
@compact_structs Animal2{T,N,J} begin
@kwdef mutable struct Wolf2{T,N}
energy::T = 0.5
ground_speed::N
const fur_color::Symbol
end
mutable struct Hawk2{T,N,J}
@kwdef mutable struct Hawk2{T,N,J}
energy::T = 0.1
ground_speed::N
flight_speed::J
end
end

abstract type AbstractSimple2 end
@compact_struct_type Simple2 <: AbstractSimple2 begin
@compact_structs Simple2 <: AbstractSimple2 begin
struct SimpleA2
x
z::Int
Expand All @@ -43,7 +44,7 @@ abstract type AbstractSimple2 end
end
end

@compact_struct_type TestOrder2 begin
@compact_structs TestOrder2 begin
struct TestOrder21
x::String
y::Float64
Expand All @@ -55,7 +56,7 @@ end
end
end

@testset "@compact_struct_type" begin
@testset "@compact_structs" begin

f = F((1,1), (1.0, 1.0), :s)
g1 = G((1,1), 1, 1, :c)
Expand Down
5 changes: 3 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ using Test
using MixedStructTypes

@testset "MixedStructTypes.jl Tests" begin
include("test_sum_struct_type_macro.jl")
include("test_compact_struct_type_macro.jl")
include("sum_structs_macro_tests.jl")
include("compact_structs_macro_tests.jl")
end

Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
@sum_struct_type @kwdef A{X,Y} begin
mutable struct B{X}

@sum_structs A{X,Y} begin
@kwdef mutable struct B{X}
a::Tuple{X, X}
b::Tuple{Float64, Float64}
const c::Symbol
end
mutable struct C
@kwdef mutable struct C
a::Tuple{Int, Int}
d::Int32
e::Bool
const c::Symbol
end
struct D{Y}
@kwdef struct D{Y}
a::Tuple{Int, Int}
f::Y
g::Tuple{Complex, Complex}
c::Symbol
end
end

@sum_struct_type @kwdef Animal{T,N,J} begin
mutable struct Wolf{T,N}
@sum_structs Animal{T,N,J} begin
@kwdef mutable struct Wolf{T,N}
energy::T = 0.5
ground_speed::N
const fur_color::Symbol
end
mutable struct Hawk{T,N,J}
@kwdef mutable struct Hawk{T,N,J}
energy::T = 0.1
ground_speed::N
flight_speed::J
end
end

abstract type AbstractSimple end
@sum_struct_type Simple <: AbstractSimple begin
@sum_structs Simple <: AbstractSimple begin
struct SimpleA
x
z::Int
Expand All @@ -43,7 +44,7 @@ abstract type AbstractSimple end
end
end

@sum_struct_type TestOrder1 begin
@sum_structs TestOrder1 begin
struct TestOrder11
x::String
y::Float64
Expand All @@ -55,7 +56,7 @@ end
end
end

@testset "@sum_struct_type" begin
@testset "@sum_structs" begin

b = B((1,1), (1.0, 1.0), :s)
c1 = C((1,1), 1, 1, :c)
Expand Down

0 comments on commit 36f11c1

Please sign in to comment.