Mixers.jl icon indicating copy to clipboard operation
Mixers.jl copied to clipboard

Generate mix or premix from existing (mixed) structs?

Open tamasgal opened this issue 5 years ago • 11 comments

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.

tamasgal avatar Apr 23 '20 21:04 tamasgal

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 :)

rafaqz avatar Apr 24 '20 02:04 rafaqz

I'll have a look. Still unsure how this should look like from the user API's perspective ;)

tamasgal avatar Apr 24 '20 06:04 tamasgal

Can you please assign this to me?

tamasgal avatar Apr 24 '20 06:04 tamasgal

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

hhaensel avatar Nov 29 '21 12:11 hhaensel

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.

rafaqz avatar Nov 29 '21 17:11 rafaqz

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?

hhaensel avatar Jun 20 '22 09:06 hhaensel

Ooops, this ended up in the wrong chat, sorry. But maybe it is still worth a thought to implement it here ... ?

hhaensel avatar Jun 20 '22 09:06 hhaensel

The approach looks great to me!

essenciary avatar Jun 21 '22 13:06 essenciary

@hhaensel what is the status of this issue?

essenciary avatar Aug 02 '22 17:08 essenciary

Well thid is an isdue of Mixers.jl and the suzhors need to comment 😉 In Stipple it's implemented

hhaensel avatar Aug 02 '22 20:08 hhaensel

I dont realy use or work on Mixers.jl anymore, but I'll review PRs.

rafaqz avatar Aug 02 '22 20:08 rafaqz