Mixers.jl
Mixers.jl copied to clipboard
Generate mix or premix from existing (mixed) structs?
First, great package, thanks for that!
Is there any fancy way to use @mix or @premix on existing mixed structs? I need a bit more nested levels...
Here is a non-working dummy example:
@premix struct FooTemplate
x
end
@FooTemplate struct Bar
y
end
# now create a @BarTemplate which contains both x and y
@premix BarTemplate Bar # this will of course not work
@BarTemplate Baz
z
end
So that Baz now has the fields x, y and z.
No, but that is a good idea. So it would need to extract the fields and type parameters of the existing struct and generate the @FooTemplate macro.
I would merge a pull request that did that :)
I'll have a look. Still unsure how this should look like from the user API's perspective ;)
Can you please assign this to me?
I've proposed something very similar with kw for Stipple.jl, but it's not yet implemented. It would be perfect to have it in your package, as we are relying on your package anyhow 😉
macro mixin(expr, prefix = "", postfix = "")
x = eval(expr)
pre = eval(prefix)
post= eval(postfix)
T = typeof(x)
values = [Stipple.Observables.to_value(getfield(x, f)) for f in fieldnames(T)]
output = quote end
for (f, type, v) in zip(Symbol.(pre, fieldnames(T), post), fieldtypes(T), values)
push!(output.args, :($(esc(f))::$type = $v) )
end
:($output)
end
julia> Base.@kwdef mutable struct NameMixin <: ReactiveModel
name::R{String} = "Knight"
surname::R{String} = "Rider"
end;
julia> Base.@kwdef mutable struct MixinExample <: ReactiveModel
name::R{String} = "Stipple!"
@mixin NameMixin() "name_" "_1"
end;
julia> propertynames(MixinExample())
(:name, :name_name_1, :name_surname_1)
EDIT: I had used the internal Stipple.@kwdef first and changed that to Base.@kwdef
Feel free to make/ updates a PR. But you should be aware that I dont actually use this package anymore... (it was my first ever Julia package!)
So I am unlikely to make any changes here personally.
Hi @essenciary, @abhimanyuaryan quite some time that this topic was raised. Now I have a new use case in StipplePlotly to follow this up.
I propose to include the following in Stipple.
macro mixin(expr, prefix = "", postfix = "")
x = eval(expr)
pre = eval(prefix)
post = eval(postfix)
T = x isa DataType ? x : typeof(x)
mix = x isa DataType ? x() : x
values = [Stipple.Observables.to_value(getfield(mix, f)) for f in fieldnames(T)]
output = quote end
for (f, type, v) in zip(Symbol.(pre, fieldnames(T), post), fieldtypes(T), values)
push!(output.args, :($(esc(f))::$type = $v) )
end
:($output)
end
and the following in StipplePlotly
const PlotlyEvent = Dict{String, Any}
@kwdef struct PlotlyEvents
_selected::R{PlotlyEvent} = PlotlyEvent()
_hover::R{PlotlyEvent} = PlotlyEvent()
_click::R{PlotlyEvent} = PlotlyEvent()
_relayout::R{PlotlyEvent} = PlotlyEvent()
end
in order to support
using Stipple
using PlotlyBase
julia> @reactive! mutable struct PlotDemo <: ReactiveModel
plot::R{Plot} = Plot()
@mixin PlotlyEvents "plot"
end
:PlotDemo
julia> fieldnames(PlotDemo)
(:plot, :plot_selected, :plot_hover, :plot_click, :plot_relayout, :channel__, :isready, :isprocessing)
I see some advanteage over the approach of Mixers.jl as there we cannot determine the position of the fields in the model, whereas here we can, and we can easily determine pre- and postfixes.
What do you think?
Ooops, this ended up in the wrong chat, sorry. But maybe it is still worth a thought to implement it here ... ?
The approach looks great to me!
@hhaensel what is the status of this issue?
Well thid is an isdue of Mixers.jl and the suzhors need to comment 😉 In Stipple it's implemented
I dont realy use or work on Mixers.jl anymore, but I'll review PRs.